scipy.stats.

ks_2samp#

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

执行双样本柯尔莫哥洛夫-斯米尔诺夫拟合优度检验。

此检验比较两个独立样本的潜在连续分布 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',则使用渐近柯尔莫哥洛夫-斯米尔诺夫分布来计算近似 p 值。如果 method='auto',如果两个样本大小都小于 10000,则尝试进行精确 p 值计算;否则,使用渐近方法。在任何情况下,如果尝试进行精确 p 值计算但失败,则会发出警告,并返回渐近 p 值。

“双侧”的“精确”计算会计算互补概率,然后从 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)

正如预期的那样,p 值 0.54 不低于我们的阈值 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 值小于我们的阈值,我们拒绝零假设而支持备择假设。