卡方检验是一种用途很广的计数资料的假设检验方法,属于非参数检验范畴。这种检验方法主要用于推断两个总体率之间有无差别、多个总体率之间有无差别、多个样本率之间的多重比较、两个分类变量之间有无关联性和频数分布拟合优度的检验等。
卡方检验的𝐻0是:实际频数与理论频数没有差别。该检验的基本思想是:假设𝐻0成立,基于此前提计算出𝜒2值,它表示观察值与理论值之间的偏离程度。根据𝜒2分布及自由度可以确定在𝐻0成立的情况下获得当前统计量及更极端情况下的概率P。如果P值很小,说明观察值与理论值偏离程度太大,应当拒绝𝐻0,表示资料之间有显著性差异。否则就不能拒绝𝐻0,尚不能认为样本所代表的实际情况和理论假设有差别。
在实际工作中,对于四格表资料,通常规定:
- 当𝑛≥40且所有的𝑇≥5时,用卡方检验的基本公式;当𝑃≈𝛼时,改用四格表的Fisher确切概率法。
- 当𝑛≥40但又1≤𝑇≤5时,用四格表资料卡方检验的校正公式。或改用四格表资料的Fisher确切概率法。
- 当𝑛<40或𝑇<1时,用四格表资料的Fisher确切概率法。
- 基本的卡方检验:stats.chi2_contingency(data,correction=False)
- 使用Yates校正的卡方检验:stats.chi2_contingency(data,correction=True)
- Fisher确切概率法:stats.fisher_exact(data,alternative='two-sided')
- 配对卡方检验(McNemar检验):tbl.mcnemar(data)
1. 基本的卡方检验
某研究者欲比较膳食干预(实验组)和普通健康教育(对照组)对糖尿病患者血糖的控制达标情况,将171例糖尿病患者随机分为两组,干预6个月后结果如下。问两组控制空腹血糖的总体达标率有无差别?
import numpy as np
from scipy import stats
bg=np.array([[30,56],[43,42]])
stats.chi2_contingency(bg,correction=False)#参数correction默认为True,表示对数据进行Yates校正。
(4.309367914097781,
0.03790304243911501,
1,
array([[36.71345029, 49.28654971],
[36.28654971, 48.71345029]]))
P=0.038<0.05,可以认为膳食干预组的空腹血糖达标率高于普通健康教育组。
bg_t=np.ones((2,2))
for i in [0,1]:
for j in [0,1]:
bg_t[i,j]=bg[i].sum()*bg[:,j].sum()/bg.sum()
((bg-bg_t)**2/bg_t).sum()
2. 使用Yates校正的卡方检验
某医师欲比较胞磷胆碱与神经节苷脂治疗脑血管疾病的疗效,将78例脑血管疾病患者随机分为两组,结果如下。问两种药物治疗脑血管疾病的有效率是否相等。
data=np.array([[46,6],[18,8]])
stats.chi2_contingency(data,correction=True)
(3.144810267857143,
0.07616885892288706,
1,
array([[42.66666667, 9.33333333],
[21.33333333, 4.66666667]]))
P=0.076>0.05,还不能认为两种药物治疗脑血管疾病的有效率不等。
3. Fisher确切概率法
某医师为研究乙肝免疫球蛋白预防胎儿宫内感染HBV的效果,将33例乙肝表面抗原(HBsAg)阳性孕妇随机分为预防注射组和非预防组,结果如下。问两组新生儿的HBV总体感染率有无差别。
data=np.array([[4,18],[5,6]])
oddsr,p=stats.fisher_exact(data,alternative='two-sided')#参数alternative有三个值,'two-sided'表示双侧检验,'less'和'greater'表示单侧检验。
# fisher_exact()返回两个值:优势比和p值。
p
0.12104475057756482
P=0.121>0.05,
还不能认为预防注射与非预防组的新生儿HBV感染率不等。
4. 配对卡方检验(McNemar检验)
某实验室分别用乳胶凝集法和免疫荧光法对58例可疑系统性红斑狼疮患者血清中抗核抗体进行测定,结果如下。问两种方法的检测结果有无差别。
import statsmodels.stats.contingency_tables as tbl
data=np.array([[11,12],[2,33]])
result=tbl.mcnemar(data)
print(result)
pvalue 0.012939453125
statistic 2.0
P=0.0129<0.05,可以认为两种方法的检测结果不同。
5. 卡方分布
卡方分布:n个独立分布(标准正态分布)的变量的平方和服从自由度为n的卡方分布。
即n个独立的标准正态随机变量的总和Y服从具有n个自由度的卡方分布。
import matplotlib.pyplot as plt
x1=np.random.normal(0,1,1000000)
x2=np.random.normal(0,1,1000000)
x3=np.random.normal(0,1,1000000)
x4=np.random.normal(0,1,1000000)
x5=np.random.normal(0,1,1000000)
x6=np.random.normal(0,1,1000000)
q1=x1**2 # n=1
q2=q1+x2**2 # n=2
q3=q2+x3**2 # n=3
q4=q3+x4**2 # n=4
q5=q4+x5**2 # n=5
q6=q5+x6**2 # n=6
fig,axs=plt.subplots(2,3,figsize=(14,8))
axs[0,0].hist(q1,100)
axs[0,0].set_title("n=1")
axs[0,1].hist(q2,100)
axs[0,1].set_title("n=2")
axs[0,2].hist(q3,100)
axs[0,2].set_title("n=3")
axs[1,0].hist(q4,100)
axs[1,0].set_title("n=4")
axs[1,1].hist(q5,100)
axs[1,1].set_title("n=5")
axs[1,2].hist(q6,100)
axs[1,2].set_title("n=6")