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_continuitybool, 可选
是否应应用连续性校正 (1/2)。当 method 为
'asymptotic'时,默认值为 True;否则无效。- alternative{‘two-sided’, ‘less’, ‘greater’}, 可选
定义备择假设。默认值为 'two-sided'。令 SX(u) 和 SY(u) 分别为分布 x 和 y 的生存函数。则以下备择假设可用:
‘two-sided’:分布不相等,即至少存在一个 u 使得 SX(u) ≠ SY(u)。
‘less’:分布 x 在随机意义上小于分布 y,即对所有 u,SX(u) < SY(u)。
‘greater’:分布 x 在随机意义上大于分布 y,即对所有 u,SX(u) > SY(u)。
在更严格的假设下,备择假设可以用分布的位置来表达;参见 [5] 第 5.1 节。
- axisint 或 None, 默认: 0
如果为 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,而不是 2Dnp.matrix。类似地,虽然被掩码数组的被掩码元素被忽略,但输出将是标量或np.ndarray,而不是带有mask=False的被掩码数组。数组 API 标准支持
mannwhitneyu除了 NumPy 之外,还对 Python Array API Standard 兼容的后端具有实验性支持。请考虑通过设置环境变量SCIPY_ARRAY_API=1并将 CuPy、PyTorch、JAX 或 Dask 数组作为数组参数提供来测试这些功能。支持以下后端和设备(或其他功能)的组合。库
CPU
GPU
NumPy
✅
不适用
CuPy
不适用
⛔
PyTorch
✅
⛔
JAX
⚠️ 无 JIT
⛔
Dask
⛔
不适用
有关更多信息,请参阅 对数组 API 标准的支持。
参考文献
[1]H.B. Mann and D.R. Whitney, “On a test of whether one of two random variables is stochastically larger than the other”, The Annals of Mathematical Statistics, Vol. 18, pp. 50-60, 1947.
[2]Mann-Whitney U Test, Wikipedia, 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 pp. 87-89.
[4] (1,2,3,4,5,6,7)Rosie Shier, “Statistics: 2.3 The Mann-Whitney U Test”, Mathematics Learning Support Centre, 2004.
[5]Michael P. Fay and Michael A. Proschan. “Wilcoxon-Mann-Whitney or t-test? On assumptions for hypothesis tests and multiple interpretations of decision rules.” Statistics surveys, Vol. 4, pp. 1-39, 2010. https://www.ncbi.nlm.nih.gov/pmc/articles/PMC2857732/
示例
我们遵循 [4] 中的示例:以下是九名随机抽样的年轻成人被诊断出患有 2 型糖尿病的年龄。
>>> 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 值足够低,可以拒绝零假设以支持备择假设。