scipy.stats.

ks_2samp#

scipy.stats.ks_2samp(data1, data2, alternative='two-sided', method='auto', *, axis=0, nan_policy='propagate', keepdims=False)[source]#

执行双样本 Kolmogorov-Smirnov 拟合优度检验。

此检验比较两个独立样本的潜在连续分布 F(x) 和 G(x)。有关可用原假设和备择假设的描述,请参见注释。

参数:
data1, data2类数组, 1 维

两个样本观测值数组,假设来自连续分布,样本大小可以不同。

alternative{‘two-sided’, ‘less’, ‘greater’}, 可选

定义原假设和备择假设。默认为 ‘two-sided’。请参见下面的注释中的说明。

method{‘auto’, ‘exact’, ‘asymp’}, 可选

定义用于计算 p 值的 方法。以下选项可用(默认为 ‘auto’)

  • ‘auto’ : 对于小尺寸数组,使用 ‘exact’,对于大尺寸数组,使用 ‘asymp’

  • ‘exact’ : 使用检验统计量的精确分布

  • ‘asymp’ : 使用检验统计量的渐近分布

axisint 或 None,默认值:0

如果为 int,则为沿其计算统计量的输入的轴。输入的每个轴切片(例如,行)的统计量将出现在输出的相应元素中。如果为 None,则在计算统计量之前将平展输入。

nan_policy{‘propagate’, ‘omit’, ‘raise’}

定义如何处理输入 NaN。

  • propagate:如果存在 NaN 的轴切片(例如,行)沿其计算统计量,则输出的相应条目将为 NaN。

  • omit:执行计算时将省略 NaN。如果在沿其计算统计量的轴切片中剩余的数据不足,则输出的相应条目将为 NaN。

  • raise:如果存在 NaN,则会引发 ValueError

keepdimsbool,默认值:False

如果将其设置为 True,则缩减的轴将保留在结果中,作为大小为 1 的维度。使用此选项,结果将针对输入数组正确广播。

返回值:
res: KstestResult

包含属性的对象

statisticfloat

KS 检验统计量。

pvaluefloat

单尾或双尾 p 值。

statistic_locationfloat

来自 data1data2 的值,对应于 KS 统计量;即,经验分布函数之间的距离在此观测值处测量。

statistic_signint

如果 data1 的经验分布函数在 statistic_location 处超过 data2 的经验分布函数,则为 +1,否则为 -1。

注释

可以使用 alternative 参数选择原假设和相应的备择假设的三个选项。

  • less:原假设是对于所有 x,F(x) >= G(x);备择假设是对于至少一个 x,F(x) < G(x)。统计量是样本的经验分布函数之间的最小(最负)差的量级。

  • greater:原假设是对于所有 x,F(x) <= G(x);备择假设是对于至少一个 x,F(x) > G(x)。统计量是样本的经验分布函数之间的最大(最正)差。

  • two-sided:原假设是两个分布相同,对于所有 x,F(x)=G(x);备择假设是它们不相同。统计量是样本的经验分布函数之间的最大绝对差。

请注意,备择假设描述了潜在分布的CDF,而不是数据的观测值。例如,假设 x1 ~ F 和 x2 ~ G。如果对于所有 x,F(x) > G(x),则 x1 中的值往往小于 x2 中的值。

如果 KS 统计量很大,则 p 值将很小,这可以作为反对原假设并支持备择假设的证据。

如果 method='exact'ks_2samp 尝试计算精确 p 值,即在原假设下获得与从数据计算的值一样极端的检验统计量值的概率。如果 method='asymp',则使用渐近 Kolmogorov-Smirnov 分布来计算近似 p 值。如果 method='auto',如果两个样本大小都小于 10000,则尝试精确 p 值计算;否则,使用渐近方法。在任何情况下,如果尝试精确 p 值计算失败,将发出警告,并返回渐近 p 值。

‘two-sided’ ‘exact’ 计算计算互补概率,然后从 1 中减去。因此,它可以返回的最小概率约为 1e-16。虽然算法本身是精确的,但对于大样本大小,可能会累积数值误差。它最适合于样本大小仅为几千的情况。

我们通常遵循 Hodges 对 Drion/Gnedenko/Korolyuk 的处理 [1]

从 SciPy 1.9 开始,在执行计算之前,np.matrix 输入(不建议用于新代码)将转换为 np.ndarray。在这种情况下,输出将是标量或适当形状的 np.ndarray,而不是 2D np.matrix。同样,虽然会忽略屏蔽数组的屏蔽元素,但输出将是标量或 np.ndarray,而不是 mask=False 的屏蔽数组。

参考文献

[1]

Hodges, J.L. Jr., “The Significance Probability of the Smirnov Two-Sample Test,” Arkiv fiur Matematik, 3, No. 43 (1958), 469-486。

示例

假设我们希望检验两个样本是否来自同一分布的原假设。我们选择 95% 的置信水平;也就是说,如果 p 值小于 0.05,我们将拒绝原假设并支持备择假设。

如果第一个样本来自均匀分布,第二个样本来自标准正态分布,我们预计原假设将被拒绝。

>>> import numpy as np
>>> from scipy import stats
>>> rng = np.random.default_rng()
>>> sample1 = stats.uniform.rvs(size=100, random_state=rng)
>>> sample2 = stats.norm.rvs(size=110, random_state=rng)
>>> stats.ks_2samp(sample1, sample2)
KstestResult(statistic=0.5454545454545454,
             pvalue=7.37417839555191e-15,
             statistic_location=-0.014071496412861274,
             statistic_sign=-1)

实际上,p 值低于我们的 0.05 阈值,因此我们拒绝原假设并支持默认的“双侧”备择假设:数据不是来自同一分布。

当两个样本都来自同一分布时,我们预计数据在大多数情况下与原假设一致。

>>> sample1 = stats.norm.rvs(size=105, random_state=rng)
>>> sample2 = stats.norm.rvs(size=95, random_state=rng)
>>> stats.ks_2samp(sample1, sample2)
KstestResult(statistic=0.10927318295739348,
             pvalue=0.5438289009927495,
             statistic_location=-0.1670157701848795,
             statistic_sign=-1)

正如预期的那样,0.54 的 p 值不低于我们的 0.05 阈值,因此我们无法拒绝原假设。

但是,假设第一个样本来自向较大值移动的正态分布。在这种情况下,潜在分布的累积密度函数 (CDF) 往往小于第二个样本的基础 CDF。因此,我们预计会使用 alternative='less' 拒绝原假设

>>> sample1 = stats.norm.rvs(size=105, loc=0.5, random_state=rng)
>>> stats.ks_2samp(sample1, sample2, alternative='less')
KstestResult(statistic=0.4055137844611529,
             pvalue=3.5474563068855554e-08,
             statistic_location=-0.13249370614972575,
             statistic_sign=-1)

事实上,由于 p 值小于我们的阈值,我们拒绝原假设并支持备择假设。