【Python・统计学】卡方检验(原理及代码)
TUTO_TUTO 2024-08-05 13:35:01 阅读 94
前言
自学笔记,分享给对统计学原理不太清楚但需要在论文中用到的小伙伴,欢迎大佬们补充或绕道。ps:本文不涉及公式讲解(文科生小白友好体质)~(部分定义等来源于知乎)
本文重点:卡方检验(非参数检验的一种)
【1.卡方检验的简单原理和前提条件】
【2.卡方检验的数据实例】
【3.卡方检验代码以及残差分析】
关于“参数检验”和“非参数检验”的不同,请参考以下文章。【统计学】参数检验和非参数检验的区别和基本统计学
1.卡方检验的简单原理和前提条件
卡方检验就是统计样本的实际观测值与理论推断值之间的偏离程度,实际观测值与理论推断值之间的偏离程度就决定卡方值的大小,如果卡方值越大,二者偏差程度越大;反之,二者偏差越小;若两个值完全相等时,卡方值就为0,表明理论值完全符合。
注意:卡方检验针对分类变量
分类变量(Categorical Variable),也称为定性变量(Qualitative Variable),是一种用于描述个体特征或属性的变量,其取值是有限个且通常没有数值意义的类别或群组。与连续变量(如身高、体重)不同,分类变量的值之间没有大小顺序或数量关系。
分类变量可分为两类:
名义变量(Nominal Variable):名义变量的类别之间没有任何自然顺序或等级关系。例如:
性别(男、女)血型(A型、B型、AB型、O型)婚姻状况(未婚、已婚、离异、丧偶)民族(汉族、满族、回族等)
有序变量(Ordinal Variable):有序变量的类别之间存在自然顺序或等级关系,但类别之间的差距没有数值意义。例如:
教育程度(小学、初中、高中、大学、研究生)问卷调查中的满意度(非常不满意、不满意、一般、满意、非常满意)产品质量等级(差、中、良、优)社会阶层(下层、中下层、中层、中上层、上层)
前提条件:
随机抽样:样本必须是从总体中随机抽取的,以确保样本具有代表性。独立性:每个观察值必须独立于其他观察值,一个观察值的分类不应影响另一个观察值的分类。样本量足够大:期望频数不应过小,一般要求每个单元格的期望频数不小于5。如果不满足这一条件,可以考虑使用Fisher精确检验或者进行单元格合并。分类变量:所有变量都应该是分类变量,即由两个或多个类别组成。互斥且穷尽:每个观察值只能属于一个类别,并且所有类别加起来应该包括所有可能的情况。
2.卡方检验的数据实例
探索【吸烟】和【肺癌】的关系
患有肺癌 | 不患肺癌 | 合计 | |
---|---|---|---|
吸烟 | 60 | 140 | 200 |
不吸烟 | 10 | 190 | 200 |
合计 | 70 | 330 | 400 |
步骤1:计算观察频数和期望频数之差的平方除以期望频数,得到每个单元格的卡方值。
期望频数的计算公式为:(行合计 × 列合计) ÷ 总合计
例如,吸烟且患有肺癌的期望频数为:(200 × 70) ÷ 400 = 35
患有肺癌 | 不患肺癌 | |
---|---|---|
吸烟 | (60 - 35)^2 ÷ 35 = 17.86 | (140 - 165)^2 ÷ 165 = 3.79 |
不吸烟 | (10 - 35)^2 ÷ 35 = 17.86 | (190 - 165)^2 ÷ 165 = 3.79 |
步骤2:将所有单元格的卡方值相加,得到总卡方值。
总卡方值 = 17.86 + 3.79 + 17.86 + 3.79 = 43.30
步骤3:根据自由度和显著性水平,查找临界卡方值。
自由度 = (行数 - 1) × (列数 - 1) = (2 - 1) × (2 - 1) = 1
假设显著性水平为0.05,查表得临界卡方值为3.84。
以下是卡方检验的临界值表,包含了不同自由度和常用显著性水平(0.10, 0.05, 0.01, 0.001)下的临界卡方值:
自由度 | 0.10 | 0.05 | 0.01 | 0.001 |
---|---|---|---|---|
1 | 2.71 | 3.84 | 6.63 | 10.83 |
2 | 4.61 | 5.99 | 9.21 | 13.82 |
3 | 6.25 | 7.81 | 11.34 | 16.27 |
4 | 7.78 | 9.49 | 13.28 | 18.47 |
5 | 9.24 | 11.07 | 15.09 | 20.52 |
6 | 10.64 | 12.59 | 16.81 | 22.46 |
7 | 12.02 | 14.07 | 18.48 | 24.32 |
8 | 13.36 | 15.51 | 20.09 | 26.12 |
9 | 14.68 | 16.92 | 21.67 | 27.88 |
10 | 15.99 | 18.31 | 23.21 | 29.59 |
11 | 17.28 | 19.68 | 24.72 | 31.26 |
12 | 18.55 | 21.03 | 26.22 | 32.91 |
13 | 19.81 | 22.36 | 27.69 | 34.53 |
14 | 21.06 | 23.68 | 29.14 | 36.12 |
15 | 22.31 | 25.00 | 30.58 | 37.70 |
16 | 23.54 | 26.30 | 32.00 | 39.25 |
17 | 24.77 | 27.59 | 33.41 | 40.79 |
18 | 25.99 | 28.87 | 34.81 | 42.31 |
19 | 27.20 | 30.14 | 36.19 | 43.82 |
20 | 28.41 | 31.41 | 37.57 | 45.32 |
步骤4:比较总卡方值和临界卡方值,如果总卡方值大于临界值,则拒绝原假设,认为变量之间存在关联。
总卡方值(43.30) > 临界卡方值(3.84),因此拒绝原假设,认为吸烟与肺癌存在关联。
这个例子说明了如何使用卡方检验来判断两个分类变量(吸烟情况和肺癌)之间是否存在关联性。通过计算观察频数与期望频数的差异,并将差异归一化后求和,得到总卡方值。将总卡方值与临界值比较,可以决定是否拒绝无关联的原假设。
3.卡方检验代码以及残差分析
残差(Residual):指在统计模型中,观察值与模型预测值之间的差异。在卡方检验中,残差表示观察频数与期望频数之间的差异。残差可以帮助我们识别哪些单元格对卡方值贡献最大,即哪些单元格的观察频数与期望频数差异最大。
<code>import numpy as np
import scipy.stats as stats
# 观察频数
observed = np.array([[60, 140], [10, 190]])
# 计算期望频数
row_totals = observed.sum(axis=1)
col_totals = observed.sum(axis=0)
total = observed.sum()
expected = np.outer(row_totals, col_totals) / total
# 计算卡方值和p值
chi2, p, dof, expected_freq = stats.chi2_contingency(observed)
# 计算标准化残差
residuals = (observed - expected) / np.sqrt(expected)
# 结果
print("观察频数:")
print(observed)
print("\n期望频数:")
print(expected)
print(f"\n卡方值: {chi2:.2f}")
print(f"p值: {p:.4f}")
print(f"自由度: {dof}")
print("\n标准化残差:")
print(residuals)
# 残差分析
print("\n残差分析:")
for i in range(residuals.shape[0]):
for j in range(residuals.shape[1]):
if abs(residuals[i, j]) > 1.96:
print(f"单元格({i+1}, {j+1})的标准化残差为{residuals[i, j]:.2f},超过1.96,有显著差异。")
else:
print(f"单元格({i+1}, {j+1})的标准化残差为{residuals[i, j]:.2f},未超过1.96,无显著差异。")
观察频数:
[[ 60 140]
[ 10 190]]
期望频数:
[[35. 165.]
[35. 165.]]
卡方值: 43.30
p值: 0.0000
自由度: 1
标准化残差:
[[ 4.23 -1.95]
[-4.23 1.95]]
残差分析:
单元格(1, 1)的标准化残差为4.23,超过1.96,有显著差异。
单元格(1, 2)的标准化残差为-1.95,未超过1.96,无显著差异。
单元格(2, 1)的标准化残差为-4.23,超过1.96,有显著差异。
单元格(2, 2)的标准化残差为1.95,未超过1.96,无显著差异。
标准化残差的绝对值大于1.96表示该单元格的观察频数与期望频数有显著差异。在这个例子中,单元格(1, 1)和(2, 1)的标准化残差超过1.96,表明吸烟者患肺癌和不吸烟者不患肺癌的观察频数显著高于期望频数。
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。