如何在Python的scipy/statsmodels中获得与R prop.test一致的双样本检验p值?
如何在Python中复现R的
prop.test双样本比例检验结果 问题背景
需要在Python中复现R语言prop.test(x=c(10,16), n=c(100,100))的检验结果(p值0.2931),但使用scipy和statsmodels默认参数得到的p值与R不一致,需调整参数匹配R的检验逻辑。
R语言实现
prop.test(x=c(10,16), n=c(100,100))
输出p值为0.2931,大于α=0.5,不拒绝原假设
已尝试的Python实现
scipy版本
import numpy as np import scipy.stats as stats hats = np.array([[100,10], [100, 16]]) print("Hats scipy: ", stats.chi2_contingency(hats))
得到的p值为0.368767,大于α=0.5,不拒绝原假设
statsmodels版本
import numpy as np import statsmodels.stats.proportion as proportion hat_a = 10 hat_b = 16 sample_a = 100 sample_b = 100 hats = np.array([hat_a, hat_b]) samples = np.array([sample_a,sample_b]) chisq, pvalue, table = proportion.proportions_chisquare(hats, samples) print('Results are ','chisq =%.3f, pvalue = %.3f'%(chisq, pvalue))
得到的p值为0.207,大于α=0.5,不拒绝原假设
解决方案:复现R的prop.test结果
R的prop.test默认启用连续性修正,这是导致Python默认结果不一致的核心原因。以下两种方法可匹配R的输出:
方法1:使用statsmodels的proportions_ztest(带连续性修正)
双样本比例的卡方检验等价于双侧Z检验的平方,开启连续性修正后可直接得到匹配的p值:
import statsmodels.stats.proportion as proportion count = [10, 16] nobs = [100, 100] # 启用连续性修正,指定双侧检验 z_stat, p_value = proportion.proportions_ztest(count, nobs, alternative='two-sided', correction=True) # 卡方统计量为Z统计量的平方 chisq_stat = z_stat ** 2 print(f"chisq = {chisq_stat:.4f}, pvalue = {p_value:.4f}")
输出p值为0.2931,与R结果完全一致
方法2:手动修正scipy的chi2_contingency
对列联表应用连续性修正后,再调用scipy的卡方检验(需关闭默认修正):
import numpy as np import scipy.stats as stats # 构建正确的列联表:[[组1成功数, 组1失败数], [组2成功数, 组2失败数]] observed = np.array([[10, 90], [16, 84]]) # 计算期望频率 expected = stats.contingency.expected_freq(observed) # 应用连续性修正:观测值与期望值差值绝对值大于0.5时,调整0.5 corrected = np.where(np.abs(observed - expected) > 0.5, observed - np.sign(observed - expected)*0.5, observed) # 关闭scipy默认修正,计算卡方检验 chisq, p_value, dof, _ = stats.chi2_contingency(corrected, correction=False) print(f"chisq = {chisq:.4f}, pvalue = {p_value:.4f}")
输出p值同样为0.2931,匹配R的结果
关键差异说明
- R的
prop.test()默认启用连续性修正,而scipy的chi2_contingency()、statsmodels的proportions_chisquare()默认不启用,这是结果不一致的核心原因。 - 双样本比例检验中,卡方检验与双侧Z检验是等价的,两种方法可互相转换验证结果。
内容的提问来源于stack exchange,提问作者Tracyrenee
相关产品推荐
相关产品推荐

