繁体   English   中英

Python 中 Chi sq 检验统计的 P 值

[英]P-value from Chi sq test statistic in Python

我计算了一个测试统计量,该统计量分布为具有 1 个自由度的卡方,并且想找出这对应于使用 python 的 P 值。

我是 python 和数学/统计新手,所以我想我在这里想要的是来自 SciPy 的 chi2 分布的概率密度函数。 但是,当我这样使用它时:

from scipy import stats
stats.chi2.pdf(3.84 , 1)
0.029846

然而,一些谷歌搜索和与一些懂数学但不懂 python 的同事交谈说它应该是 0.05。

有任何想法吗? 干杯,戴维

在这里快速复习:

概率密度函数:把它看成一个点值; 给定点的概率有多密集?

累积分布函数:这是函数到给定点的概率质量; 分布的多少百分比位于这一点的一侧?

在你的情况下,你拿了 PDF,你得到了正确的答案。 如果您尝试 1 - CDF:

>>> 1 - stats.chi2.cdf(3.84, 1)
0.050043521248705147

PDF格式 文件

要计算给定卡方和和自由度的原假设概率,您还可以调用chisqprob

>>> from scipy.stats import chisqprob
>>> chisqprob(3.84, 1)
0.050043521248705189

注意:

chisqprob已弃用。 stats.chisqprob 在 scipy 0.17;0; 中被弃用使用stats.distributions.chi2.sf代替

更新:如前所述,chisqprob() 在 scipy 版本 0.17.0 及更高版本中已弃用。 现在可以通过 scipy.stats.distributions.chi2.sf() 获得高精度卡方值,例如:

>>>from scipy.stats.distributions import chi2
>>>chi2.sf(3.84,1)
0.050043521248705189
>>>chi2.sf(1424,1)
1.2799986253099803e-311

虽然 stats.chisqprob() 和 1-stats.chi2.cdf() 对于小的卡方值似乎具有可比性,但对于大的卡方值,前者更可取。 后者不能提供小于机器 epsilon 的 p 值,并且会给出接近机器 epsilon 的非常不准确的答案。 正如其他人所展示的那样,使用这两种方法可比较的值会产生较小的卡方值:

>>>from scipy.stats import chisqprob, chi2
>>>chisqprob(3.84,1)
0.050043521248705189
>>>1 - chi2.cdf(3.84,1)
0.050043521248705147

使用 1-chi2.cdf() 在这里分解:

>>>1 - chi2.cdf(67,1)
2.2204460492503131e-16
>>>1 - chi2.cdf(68,1)
1.1102230246251565e-16
>>>1 - chi2.cdf(69,1)
1.1102230246251565e-16
>>>1 - chi2.cdf(70,1)
0.0

而 chisqprob() 为更大范围的卡方值提供准确的结果,产生的 p 值几乎与大于零的最小浮点数一样小,直到它也下溢:

>>>chisqprob(67,1)
2.7150713219425247e-16
>>>chisqprob(68,1)
1.6349553217245471e-16
>>>chisqprob(69,1)
9.8463440314253303e-17    
>>>chisqprob(70,1)
5.9304458500824782e-17
>>>chisqprob(500,1)
9.505397766554137e-111
>>>chisqprob(1000,1)
1.7958327848007363e-219
>>>chisqprob(1424,1)
1.2799986253099803e-311
>>>chisqprob(1425,1)
0.0

你的意思是:

>>> 1 - stats.chi2.cdf(3.84, 1)
0.050043521248705147

其他一些解决方案已弃用。 使用scipy.stats.chi2生存函数。 1 - cdf(chi_statistic, df)相同

例子:

from scipy.stats import chi2
p_value = chi2.sf(chi_statistic, df)

如果您想理解数学,样本的 p 值 x(固定)是

P[P(X) <= P(x)] = P[m(X) >= m(x)] = 1 - G(m(x)^2)

在哪里,

  • P 是具有已知协方差 (cov) 和均值的(比如 k 变量)正态分布的概率,
  • X 是来自该正态分布的随机变量,
  • m(x) 是马氏距离 = sqrt( < cov^{-1} (x-mean), x-mean >。请注意,在 1-d 中,这只是 z 分数的绝对值。
  • G 是具有 k 个自由度的 chi^2 分布的 CDF。

因此,如果您正在计算固定观察值 x 的 p 值,那么您将计算 m(x)(广义 z 分数)和 1-G(m(x)^2)。

例如,众所周知,如果 x 从单变量 (k = 1) 正态分布中采样并且 z-score = 2(与均值相差 2 个标准差),则 p 值约为 .046(参见z 分数表)

In [7]: from scipy.stats import chi2

In [8]: k = 1

In [9]: z = 2

In [10]: 1-chi2.cdf(z**2, k)
Out[10]: 0.045500263896358528

对于超高精度,当 scipy 的chi2.sf()不够时,请拿出大炮:

>>> import numpy as np
>>> from rpy2.robjects import r
>>> np.exp(np.longdouble(r.pchisq(19000, 2, lower_tail=False, log_p=True)[0]))
1.5937563168532229629e-4126

由另一个用户更新(WestCoastProjects)当使用来自 OP 的值时,我们得到:

np.exp(np.longdouble(r.pchisq(3.84,1, lower_tail=False, log_p=True)[0]))
Out[5]: 0.050043521248705198928

这就是您要找的0.05

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM