【问题标题】:Run a chi square test with observation and expectation counts and get confidence interval使用观察和期望计数运行卡方检验并获得置信区间
【发布时间】:2017-01-07 10:09:12
【问题描述】:

我是卡方检验的新手,我试图弄清楚运行卡方检验的“标准”方法是什么,并且还获得了两个实验中成功率差异的 95% 置信区间。

我的数据如下所示:

Condition A:    25           75           100
Condition B:    100          100          200
Total:          125          175

这些数字代表实验期间观察到的内容的计数。如您所见,条件 A 和条件 B 的样本数量并不相同。

我想得到的是:

  1. 一个测试统计量,表明条件 A 的 33% 成功率是否与条件 B 的 50% 成功率在统计上不同。
  2. 我还想获得两个成功率之间差异的 95% 置信区间。

scipy.stats.chisquare 似乎希望用户调整“预期”计数,以便它们看起来与“观察到”计数的样本量相同。这是我唯一需要做的转变吗?如果没有,我还需要做什么?最后,我将如何计算比例差异的 95% 置信区间?

【问题讨论】:

  • 我认为卡方不适合您想要的测试。
  • 每一列的值是多少?它是在 csv 文件中还是在其他文件中?请edit您的问题并添加此重要信息。
  • @martineau 我已经添加了一点澄清。
  • @juanpa.arrivillaga 我相信这是分类数据卡方应用的经典示例。
  • 抱歉,这样也好不了多少。第一列是不言自明的,但重要的是要知道接下来的两列中的哪一列是成功和失败的计数(假设最后一列是它们的总数)。此外,您还没有提到数据的格式。它是在文件中还是在内存中的数据结构中或其他东西中。我们不是读心术...

标签: python scipy statistics chi-squared


【解决方案1】:

您有一个contingency table。要对此数据进行 χ2 检验,可以使用scipy.stats.chi2_contingency

In [31]: from scipy.stats import chi2_contingency

In [32]: obs = np.array([[25, 75], [100, 100]])

In [33]: obs
Out[33]: 
array([[ 25,  75],
       [100, 100]])

In [34]: chi2, p, dof, expected = chi2_contingency(obs)

In [35]: p
Out[35]: 5.9148695289823149e-05

您的列联表是 2x2,因此您可以使用 Fisher's exact test。这在 scipy 中实现为 scipy.stats.fisher_exact:

In [148]: from scipy.stats import fisher_exact

In [149]: oddsr, pval = fisher_exact(obs)

In [150]: pval
Out[150]: 3.7175015403965242e-05

scipy 没有更多的列联表。看起来statsmodels 的下一个版本将有更多用于分析列联表的工具,但现在没有帮助。

编写一些代码来计算比例差异及其 95% 置信区间并不难。这是一种方法:

# Include this if you are using Python 2.7.  Or tweak the code in the
# function to ensure that division uses floating point.
from __future__ import division


def diffprop(obs):
    """
    `obs` must be a 2x2 numpy array.

    Returns:
    delta
        The difference in proportions
    ci
        The Wald 95% confidence interval for delta
    corrected_ci
        Yates continuity correction for the 95% confidence interval of delta.
    """
    n1, n2 = obs.sum(axis=1)
    prop1 = obs[0,0] / n1
    prop2 = obs[1,0] / n2
    delta = prop1 - prop2

    # Wald 95% confidence interval for delta
    se = np.sqrt(prop1*(1 - prop1)/n1 + prop2*(1 - prop2)/n2)
    ci = (delta - 1.96*se, delta + 1.96*se)

    # Yates continuity correction for confidence interval of delta
    correction = 0.5*(1/n1 + 1/n2)
    corrected_ci = (ci[0] - correction, ci[1] + correction)

    return delta, ci, corrected_ci

例如,

In [22]: obs
Out[22]: 
array([[ 25,  75],
       [100, 100]])

In [23]: diffprop(obs)
Out[23]: 
(-0.25,
 (-0.35956733089748971, -0.14043266910251032),
 (-0.36706733089748972, -0.13293266910251031))

返回的第一个值是比例差delta。接下来的两对是 delta 的 Wald 95% 置信区间和 Yates 连续性校正的 Wald 95% 置信区间。

如果你不喜欢那些负值,你可以先反转行:

In [24]: diffprop(obs[::-1])
Out[24]: 
(0.25,
 (0.14043266910251032, 0.35956733089748971),
 (0.13293266910251031, 0.36706733089748972))

为了比较,这里是 R 中的类似计算:

> obs
     [,1] [,2]
[1,]   25   75
[2,]  100  100
> prop.test(obs, correct=FALSE)

    2-sample test for equality of proportions without continuity
    correction

data:  obs
X-squared = 17.1429, df = 1, p-value = 3.467e-05
alternative hypothesis: two.sided
95 percent confidence interval:
 -0.3595653 -0.1404347
sample estimates:
prop 1 prop 2 
  0.25   0.50 

> prop.test(obs, correct=TRUE)

    2-sample test for equality of proportions with continuity correction

data:  obs
X-squared = 16.1297, df = 1, p-value = 5.915e-05
alternative hypothesis: two.sided
95 percent confidence interval:
 -0.3670653 -0.1329347
sample estimates:
prop 1 prop 2 
  0.25   0.50

【讨论】:

  • 哇,非常感谢您提供如此全面的答案!
【解决方案2】:

我只想在Warren's great answer 中添加n1 = float(n1)n2 = float(n2)。它们应该被转换为浮点数(对于 Python 2 用户),否则除法将简单地产生 0。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-13
    • 2018-12-30
    • 2020-08-22
    • 2013-02-25
    • 2013-03-13
    • 2019-03-06
    • 1970-01-01
    相关资源
    最近更新 更多