如何在 SciPy 中正确使用 Kolmogorov Smirnov 测试?

Posted

技术标签:

【中文标题】如何在 SciPy 中正确使用 Kolmogorov Smirnov 测试?【英文标题】:How to properly use Kolmogorov Smirnoff test in SciPy? 【发布时间】:2018-06-01 06:21:29 【问题描述】:

我有一个分布

这个看起来很高斯,我们也不能拒绝 KS 测试中 p 值如此高的想法。

但是,测试分布实际上也是一个具有有限样本大小的生成分布,而不是 CDF 本身,正如您将在代码中注意到的那样。因此,与使用 CDF 获得平滑高斯函数相比,这是一种作弊。

from scipy import stats
import numpy as np
import matplotlib.pyplot as plt

np.random.seed(1)

d1 = np.random.normal(loc = 3, scale = 2, size = 1000)
d2 = np.random.normal(loc = 3, scale = 0.5, size = 250) # Vary this to test

data = np.concatenate((d1,d2))

xmin, xmax = min(data), max(data)
lnspc = np.linspace(xmin, xmax, len(data))

# lets try the normal distribution first
m, s = stats.norm.fit(data)         # get mean and standard deviation from fit
pdf_g = stats.norm.pdf(lnspc, m, s) # now get theoretical values in our interval
plt.hist(data, color = "lightgrey", normed = True, bins = 50)
plt.plot(lnspc, pdf_g, color = "black", label="Gaussian") # plot it


# Test how not-gaussian our distribution is by generating a distribution from the fit
test_dist = np.random.normal(m, s, len(data))
KS_D, KS_p = stats.ks_2samp(data, test_dist)
plt.title("D = 0:.2f, p = 1:.2f".format(KS_D, KS_p))

plt.show()

但我不知道如何使用默认的 KS 测试,即

KS_D, KS_p = stats.kstest(data, "norm"),

因为它总是返回一个 0 的 p 值,即我的高斯数据必须是错误的格式。

我应该如何标准化我的数据以正确使用 KS 测试? 模拟比较分布是一种有效的用法,还是比针对分布的连续 CDF 进行测试更不正确?

【问题讨论】:

您正在将正态分布数据的拟合与正态分布进行比较。它们应该是相同的,因此您不能拒绝原假设。返回的 D 值是多少? 如果我与生成的有限正态分布进行比较,我得到 D = 0.04,p = 0.49,正如将高斯与高斯进行比较时所预期的那样。但是,如果我写 KS_D, KS_p = stats.kstest(data, "norm") 我得到 D = 0.73 和 p = 0。所以我这样做的方式一定有问题。 【参考方案1】:

"norm" 使用默认为零均值的正态分布,标准差为 1 [ref]。您的数据具有 ms 的值,它们完全不同。它告诉您它们与此标准参考分布非常不同。

如果您首先适当地标准化(哈哈)您的数据,您仍然可以使用此测试来检查数据是否看起来像高斯:

data_n = (data - m) / s
KS_D, KS_p = stats.kstest(data_n, "norm")

【讨论】:

以上是关于如何在 SciPy 中正确使用 Kolmogorov Smirnov 测试?的主要内容,如果未能解决你的问题,请参考以下文章

scipy.sparse.csr_matrix 行过滤 - 如何正确实现?

使用 JAX 和 SciPy 对不正确积分进行微分

使用自制 Python 在 Mac 10.8 上安装 scipy 的正确位置是啥?

如何使用 python + NumPy / SciPy 计算滚动/移动平均值?

用 scipy 获取置信区间的正确方法

如何将 numpy.matrix 或数组转换为 scipy 稀疏矩阵