scipy.stats.

mannwhitneyu#

scipy.stats.mannwhitneyu(x, y, use_continuity=True, alternative='two-sided', axis=0, method='auto', *, nan_policy='propagate', keepdims=False)[源代码]#

对两个独立样本执行 Mann-Whitney U 秩检验。

Mann-Whitney U 检验是一种用于检验样本 x 所基于的分布与样本 y 所基于的分布是否相同的非参数检验。它通常用作检验分布间位置差异的一种检验方法。

参数:
x, y类似数组

N 维样本数组。这些数组必须可广播,但在 axis 给出的维度除外。

use_continuity布尔值,可选

是否应用连续性校正 (1/2)。当method'asymptotic' 时,默认为 True;否则无效。

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

定义备择假设。默认为‘two-sided’。设F(u)G(u) 分别是 xy 分布基础的累积分布函数。则可以使用下列备择假设

  • ‘two-sided’:分布不相等,即至少存在一个 u 使得 F(u) ≠ G(u)

  • ‘less’:以 x 为基础的分布在随机性上比以 y 为基础的分布小,即对于所有 u 而言,F(u) > G(u)

  • ‘greater’:以 x 为基础的分布在随机性上比以 y 为基础的分布大,即对于所有 u 而言,F(u) < G(u)

请注意,上述备择假设中的数学表达式描述了基础分布的累积分布函数。乍一看,这些不等式的方向似乎与自然语言描述不一致,但事实并非如此。例如,假设 XY 是随机变量,分别遵循具有累积分布函数 FG 的分布。如果对于所有 u 而言,F(u) > G(u),则从 X 中抽取的样本往往小于从 Y 中抽取的样本。

在更具限制性的假设集合中,备择假设可以使用分布位置表示;请参阅 [5] 的第 5.1 节。

axisint 或 None,默认值:0

如果为 int,则按该 int 轴计算统计量。输入的每个轴切片(例如行)的统计量将显示在输出的对应元素中。如果为None,则将在计算统计量之前对输入进行卷积。

method{‘auto’, ‘asymptotic’, ‘exact’} 或 PermutationMethod 实例,可选

选择用于计算p值的算法。默认为‘auto’。可以使用下列选项。

  • 'asymptotic':将标准化检验统计量与正态分布进行比较,并校正关系。

  • 'exact':通过将观察到的 \(U\) 统计量与零假设下 \(U\) 统计量的精确分布进行比较来计算精确p值。不校正关系。

  • 'auto':当其中一个样本的大小小于或等于 8 且没有并列时,选择 'exact';否则选择 'asymptotic'

  • PermutationMethod 实例。在这种情况下,p 值使用 permutation_test 计算,其中包括所提供的配置选项和其他适当的设置。

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

定义如何处理输入 NaN。

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

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

  • raise:如果出现 NaN,则会引发 ValueError

keepdimsbool,默认值:False

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

返回:
resMannwhitneyuResult

包含属性的对象

statisticfloat

与样本 x 对应的 Mann-Whitney U 统计信息。请参阅备注,以了解与样本 y 对应的检验统计信息。

pvaluefloat

所选 alternative 的关联 p 值。

备注

如果 U1 是与样本 x 对应的统计量,那么与样本 y 对应的统计量是 U2 = x.shape[axis] * y.shape[axis] - U1

mannwhitneyu 适用于独立样本。对于相关/成对样本,请考虑 scipy.stats.wilcoxon

method 'exact' 建议在没有并列关系,且任意样本大小均小于 8 [1] 时使用。实现遵循 [3] 中报告的算法。请注意,精确方法没有针对并列关系进行校正,但当数据中存在并列关系时,mannwhitneyu 不会引发错误或警告。如果存在并列关系,且任意样本很小(少于 ~10 次观测),请考虑将 PermutationMethod 的实例作为 method 传递,以执行置换检验。

Mann-Whitney U 检验是独立样本的 t 检验的非参数版本。当来自该总体的样本的平均值呈正态分布时,请考虑 scipy.stats.ttest_ind

从 SciPy 1.9 开始,np.matrix 输入(不建议用于新代码)会在执行计算之前转换为 np.ndarray。在这种情况下,输出将是标量或对应形状的 np.ndarray,而不是 2D np.matrix。类似地,蒙版数组的蒙版元素虽被忽略,但输出仍将是标量或 np.ndarray,而不是蒙版为 mask=False 的蒙版数组。

参考

[1]

H.B. Mann 和 D.R. Whitney,关于一个随机变量比另一个随机变量随机较大的检验,数学统计年鉴,第 18 卷,第 50-60 页,1947 年。

[2]

Mann-Whitney U 检验,维基百科,http://en.wikipedia.org/wiki/Mann-Whitney_U_test

[3]

Andreas Löffler,“Über eine Partition der nat. Zahlen und ihr Anwendung beim U-Test”,Wiss. Z. Univ. Halle, XXXII’83 第 87-89 页。

[4] (1,2,3,4,5,6,7)

Rosie Shier,“统计:2.3 Mann-Whitney U 检验”,数学学习支持中心,2004 年。

[5]

Michael P. Fay 和 Michael A. Proschan。“Wilcoxon-Mann-Whitney 检验还是 t 检验?对假设检验和决策规则的多种解释”,统计调查,第 4 卷,第 1-39 页,2010 年。https://www.ncbi.nlm.nih.gov/pmc/articles/PMC2857732/

示例

我们按照 [4] 中的示例:随机抽取的九名年轻成年人被诊断出患有 II 型糖尿病,年龄如下。

>>> males = [19, 22, 16, 29, 24]
>>> females = [20, 11, 17, 12]

我们使用 Mann-Whitney U 检验来评估男性和女性的诊断年龄是否存在统计学上的显着差异。原假设是男性诊断年龄的分布与女性诊断年龄的分布相同。我们决定需要 95% 的置信水平才能拒绝原假设,得出的结论是分布不同。由于样本数量非常小,并且数据中没有绑定,因此我们可以将观察到的检验统计量与原假设下检验统计量的精确分布进行比较。

>>> from scipy.stats import mannwhitneyu
>>> U1, p = mannwhitneyu(males, females, method="exact")
>>> print(U1)
17.0

mannwhitneyu 始终报告与第一个样本(在本例中为男性)关联的统计量。这与 [4] 中报告的 \(U_M = 17\) 一致。与第二个统计量相关的统计量可以计算为

>>> nx, ny = len(males), len(females)
>>> U2 = nx*ny - U1
>>> print(U2)
3.0

这与 [4] 中报告的 \(U_F = 3\) 一致。双边p值可以从任一统计量中计算,而 mannwhitneyu 生成的值与 [4] 中报告的 \(p = 0.11\) 一致。

>>> print(p)
0.1111111111111111

检验统计量的精确分布渐近正态分布,因此该示例继续将精确p值与使用正态近似产生的p值进行比较。

>>> _, pnorm = mannwhitneyu(males, females, method="asymptotic")
>>> print(pnorm)
0.11134688653314041

这里 mannwhitneyu 报告的 p 值似乎与在 [4] 中给出的值 \(p = 0.09\) 冲突。原因是 [4] 没有应用由 mannwhitneyu 执行的连续性修正;mannwhitneyu 将检验统计量与均值 \(\mu = n_x n_y / 2\) 之间的距离减少了 0.5,以纠正离散统计量与连续分布进行比较这一事实。这里,所使用的 \(U\) 统计量小于均值,所以我们在分子中添加 0.5 来减少距离。

>>> import numpy as np
>>> from scipy.stats import norm
>>> U = min(U1, U2)
>>> N = nx + ny
>>> z = (U - nx*ny/2 + 0.5) / np.sqrt(nx*ny * (N + 1)/ 12)
>>> p = 2 * norm.cdf(z)  # use CDF to get p-value from smaller statistic
>>> print(p)
0.11134688653314041

如果需要,我们也可以禁用连续性修正,以获取与在 [4] 中报告的结果一致的结果。

>>> _, pnorm = mannwhitneyu(males, females, use_continuity=False,
...                         method="asymptotic")
>>> print(pnorm)
0.0864107329737

无论我们执行的是精确检验还是渐近检验,检验统计量偶然达到或超过该值极端的概率都超过 5%,因此我们不认为结果具有统计学意义。

假设在看到数据之前,我们对女性比男性更可能被诊断出较年轻这一假设进行了假设检验。在这种情况下,将女性年龄作为第一个输入是自然的,并且我们已经使用 alternative = 'less' 执行了一个单边检验:女性被诊断出的年龄随机小于男性年龄。

>>> res = mannwhitneyu(females, males, alternative="less", method="exact")
>>> print(res)
MannwhitneyuResult(statistic=3.0, pvalue=0.05555555555555555)

同样,在原假设下通过偶然获得足够低的检验统计量值概率大于 5%,因此我们不拒绝原假设,而赞成我们的备选假设。

如果假设来自总体样本的均值服从正态分布,那么我们就可以使用 t 检验来执行分析。

>>> from scipy.stats import ttest_ind
>>> res = ttest_ind(females, males, alternative="less")
>>> print(res)
TtestResult(statistic=-2.239334696520584,
            pvalue=0.030068441095757924,
            df=7.0)

在此假设下,p 值将足够低,以拒绝原假设,而赞成备选假设。