python - 当我对大型数据集使用 scipy.stats.kstest() 时,p_value 为 0

标签 python testing scipy normal-distribution kolmogorov-smirnov

我有一个具有频率的独特系列,想知道它们是否来自正态分布,所以我使用 scipy.stats.kstest 进行了 Kolmogorov–Smirnov 测试。因为,据我所知,该函数只接受一个列表,所以我在将频率放入函数之前将频率转换为一个列表。然而,结果很奇怪,因为 pvalue=0.0

原始数据的直方图和我的代码如下: Histogram of my dataset

[In]: frequencies = mp[['c','v']]

[In]: print frequencies
         c      v
31  3475.8   18.0
30  3475.6   12.0
29  3475.4   13.0
28  3475.2    8.0
20  3475.0   49.0
14  3474.8   69.0
13  3474.6   79.0
12  3474.4   78.0
11  3474.2   78.0
7   3474.0  151.0
6   3473.8  157.0
5   3473.6  129.0
2   3473.4  149.0
1   3473.2  162.0
0   3473.0  179.0
3   3472.8  145.0
4   3472.6  139.0
8   3472.4   95.0
9   3472.2  103.0
10  3472.0  125.0
15  3471.8   56.0
16  3471.6   75.0
17  3471.4   70.0
18  3471.2   70.0
19  3471.0   57.0
21  3470.8   36.0
22  3470.6   22.0
23  3470.4   20.0
24  3470.2   12.0
25  3470.0   23.0
26  3469.8   13.0
27  3469.6   17.0
32  3469.4    6.0

[In]: testData = map(lambda x: np.repeat(x[0], int(x[1])), frequencies.values)

[In]: testData = list(itertools.chain.from_iterable(testData))

[In]: print len(testData)
2415

[In]: print np.unique(testData)
[ 3469.4  3469.6  3469.8  3470.   3470.2  3470.4  3470.6  3470.8  3471.
  3471.2  3471.4  3471.6  3471.8  3472.   3472.2  3472.4  3472.6  3472.8
  3473.   3473.2  3473.4  3473.6  3473.8  3474.   3474.2  3474.4  3474.6
  3474.8  3475.   3475.2  3475.4  3475.6  3475.8]

[In]: scs.kstest(testData, 'norm')
KstestResult(statistic=1.0, pvalue=0.0)

先谢谢大家

最佳答案

使用 'norm' 作为您的输入将检查您的数据分布是否与具有默认参数的 scipy.stats.norm.cdf 相同:位置=0,比例=1

相反,您需要使数据符合正态分布,然后使用 Kolmogorov–Smirnov 检验检查数据和分布是否相同。

import numpy as np
from scipy.stats import norm, kstest
import matplotlib.pyplot as plt

freqs = [[3475.8, 18.0], [3475.6, 12.0], [3475.4, 13.0], [3475.2, 8.0], [3475.0, 49.0],
    [3474.8, 69.0], [3474.6, 79.0], [3474.4, 78.0], [3474.2, 78.0], [3474.0, 151.0],
    [3473.8, 157.0], [3473.6, 129.0], [3473.4, 149.0], [3473.2, 162.0], [3473.0, 179.0],
    [3472.8, 145.0], [3472.6, 139.0], [3472.4, 95.0], [3472.2, 103.0], [3472.0, 125.0],
    [3471.8, 56.0], [3471.6, 75.0], [3471.4, 70.0], [3471.2, 70.0], [3471.0, 57.0],
    [3470.8, 36.0], [3470.6, 22.0], [3470.4, 20.0], [3470.2, 12.0], [3470.0, 23.0],
    [3469.8, 13.0], [3469.6, 17.0], [3469.4, 6.0]]

data = np.hstack([np.repeat(x,int(f)) for x,f in freqs])
loc, scale = norm.fit(data)
# create a normal distribution with loc and scale
n = norm(loc=loc, scale=scale)

绘制标准与数据的拟合:

plt.hist(data, bins=np.arange(data.min(), data.max()+0.2, 0.2), rwidth=0.5)
x = np.arange(data.min(), data.max()+0.2, 0.2)
plt.plot(x, 350*n.pdf(x))
plt.show()

enter image description here

这不太合适,主要是因为左边的长尾部。但是,您现在可以使用拟合正态分布的 cdf 运行正确的 Kolmogorov–Smirnov 检验

kstest(data, n.cdf)
# returns:
KstestResult(statistic=0.071276854859734784, pvalue=4.0967451653273201e-11)

因此,我们仍然拒绝产生数据的分布与拟合分布相同的原假设。

关于python - 当我对大型数据集使用 scipy.stats.kstest() 时,p_value 为 0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46678239/

相关文章:

java - 对抽象类的扩展进行强制测试

python - 为什么我无法使用 scipy.optimize.curve_fit 将 sigmoid 函数拟合到此数据?

python - 多数过滤器 Numpy 数组

python - 我怎样才能让 Python 找到 ffprobe?

python - 了解请求与 grequests

python - 我该怎么做才能使 Eclipse PyDev 编辑器更具 react 性?

python - 在样条拟合的一维数据中找到拐点

python - 用 Pandas 转换日期列

php - 当我获取/转储列表时,redis (PHP) 中的 LPUSH 函数抛出 bool(false)

hibernate - 在 gradle 中执行 bash 脚本