python chi2_contingency卡方检验简介用法示例详解
简介
scipy.stats.chi2_contingency是一个计算列联表中变量相互独立的卡方检验的函数。它根据列联表中的观察频率计算卡方统计量和p值。期望频率是根据假设独立性的条件下的边际和来计算的;详情请参见
scipy.stats.contingency.expected_freq`。自由度的数量(使用numpy函数和属性来表示):
dof = observed.size - sum(observed.shape) + observed.ndim - 1
参数
observed
:array_like类型,列联表。表中包含每个类别中的观察频率(即出现次数)。在二维情况下,该表通常被描述为“R x C表”。correction
:bool类型,可选参数,默认为True。如果为True,并且自由度为1,则应用Yates’修正。修正的效果是将每个观察值调整0.5个单位至相应的期望值方向。lambda_
:float类型或str类型,可选参数。默认情况下,在此检验中计算的统计量为Pearson的卡方统计量。lambda_
允许使用Cressie-Read幂差异系列中的统计量。详情请参见scipy.stats.power_divergence
。
返回值
返回一个Chi2ContingencyResult对象,该对象具有以下属性:
statistic
:float类型,测试统计量。pvalue
:float类型,检验的p值。dof
:int类型,自由度。expected_freq
:ndarray,与观察值具有相同形状的数组。根据表的边际和计算的期望频率。
注意事项
- 一个经常提到的关于此计算有效性的指导原则是,只有在每个单元格中观察到的和期望的频率至少为5时,才应使用该检验。
- 这是对不同类别的人口特征独立性的检验。当观察的维数为两个或更多时,该检验才具有意义。将该检验应用于一维表将始终导致期望值等于观察值且卡方统计量等于0。
- 该函数不处理掩码数组,因为在缺失值情况下,计算无意义。
- 与
scipy.stats.chisquare
类似,该函数计算卡方统计量。该函数提供的便利性在于从给定的列联表中找到期望频率和自由度。如果这些已知,并且不需要Yates’修正,则可以使用scipy.stats.chisquare
。即,如果调用:
res = chi2_contingency(obs, correction=False)
则以下等式成立:
pythonCopy code(res.statistic, res.pvalue) == stats.chisquare(obs.ravel(),
f_exp=ex.ravel(),
ddof=obs.size - 1 - dof)
lambda_
参数在scipy
的0.13.0版本中添加。
参考文献
[1] “Contingency table”, https://en.wikipedia.org/wiki/Contingency_table [2] “Pearson’s chi-squared test”, https://en.wikipedia.org/wiki/Pearson%27s_chi-squared_test [3] Cressie, N. and Read, T. R. C., “Multinomial Goodness-of-Fit Tests”, J. Royal Stat. Soc. Series B, Vol. 46, No. 3 (1984), pp. 440-464. [4] Berger, Jeffrey S. et al. “Aspirin for the Primary Prevention of Cardiovascular Events in Women and Men: A Sex-Specific Meta-analysis of Randomized Controlled Trials.” JAMA, 295(3):306-313, DOI:10.1001/jama.295.3.306, 2006.
示例
在[4]中,研究了使用阿司匹林预防男女心血管事件。研究特别得出以下结论: “由于减少女性缺血性中风风险,阿司匹林治疗减少了心血管事件的复合风险…” 文章列出了各种心血管事件的研究。我们将重点关注女性的缺血性中风。 下表总结了参与者定期服用阿司匹林或安慰剂的实验结果。记录了缺血性中风的病例:
阿司匹林 安慰剂
缺血性中风 176 230
无中风 21035 21018
是否有证据表明阿司匹林降低了缺血性中风的风险?我们首先提出一个原假设: 阿司匹林的效果与安慰剂相当。 让我们用卡方检验评估这个假设的合理性。
import numpy as np
from scipy.stats import chi2_contingency
table = np.array([[176, 230], [21035, 21018]])
res = chi2_contingency(table)
res.statistic
6.892569132546561
res.pvalue
0.008655478161175739
在显著水平为5%的情况下,我们将拒绝原假设,接受备择假设:“阿司匹林的效果与安慰剂的效果不相等”。由于scipy.stats.contingency.chi2_contingency
执行的是双侧检验,备择假设并没有指示效果的方向。我们可以使用stats.contingency.odds_ratio
来支持以下结论:阿司匹林降低了缺血性中风的风险。 下面是更多示例,展示如何对更大的列联表进行检验。 一个二维的例子(2行3列):
obs = np.array([[10, 10, 20], [20, 20, 20]])
res = chi2_contingency(obs)
res.statistic
2.7777777777777777
res.pvalue
0.24935220877729619
res.dof
2
res.expected_freq
array([[ 12., 12., 16.],
[ 18., 18., 24.]])
使用对数似然比(即“G-test”)而不是Pearson的卡方统计量进行检验。
res = chi2_contingency(obs, lambda_="log-likelihood")
res.statistic
2.7688587616781319
res.pvalue
0.25046668010954165
一个四维的例子(2行2列2层2块):
obs = np.array(
[[[[12, 17],
[11, 16]],
[[11, 12],
[15, 16]]],
[[[23, 15],
[30, 22]],
[[14, 17],
[15, 16]]]])
res = chi2_contingency(obs)
res.statistic
8.7584514426741897
res.pvalue
0.64417725029295503