scipy.stats.

shapiro#

scipy.stats.shapiro(x, *, axis=None, nan_policy='propagate', keepdims=False)[源代码]#

对正态性执行 Shapiro-Wilk 检验。

Shapiro-Wilk 检验检验了以下零假设:数据是从正态分布中提取的。

参数:
xarray_like

样本数据的数组。必须至少包含三个观测值。

axisint 或 None,默认值:None

如果为 int,则为计算统计数据的输入的轴。每个轴分片(例如,行)的输入统计数据将出现在其对应元素中。如果 None,则在计算统计数据之前,输入将被展平。

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

定义如何处理输入的 NaN。

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

  • 省略: 在执行计算时将忽略 NaN。如果统计信息计算后,在轴切片中仍然有不足够的数据,则输出的相应输入将为 NaN。

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

keepdimsbool,默认值:False

如果将此项设为 True,则减少的轴将被保留在结果中,作为大小为一的维度。使用此选项,结果将针对输入阵列正确进行广播。

返回:
统计信息float

测试统计信息。

p 值float

假设检验的 p 值。

另请参见

anderson

正态性的 Anderson-Darling 检验

kstest

拟合优度的 Kolmogorov-Smirnov 检验。

备注

所用算法在 [4] 中有所描述,但并未实现所述的审查参数。对于 N > 5000,W 测试统计信息是准确的,但 p 值可能不准确。

在 SciPy 1.9 中,np.matrix 输入(不建议用于新的代码)将在执行计算前转换为 np.ndarray。这样一来,输出将是标量或相应形状的 np.ndarray,而不是二维 np.matrix。同样,虽然会忽略掩码阵列的掩码元素,但输出将是标量或 np.ndarray,而不是 mask=False 的掩码阵列。

引文

[2] (1,2)

Shapiro, S. S. & Wilk, M.B, “正态性方差分析检验(完整样本)”,生物统计学,1965 年,第 52 卷,第 591-611 页,DOI:10.2307/2333709

[3]

Razali, N. M. & Wah, Y. B., “Shapiro-Wilk、Kolmogorov-Smirnov、Lilliefors 和 Anderson-Darling 检验的功效比较”,统计建模和分析杂志,2011 年,第 2 卷,第 21-33 页。

[4]

Royston P.,“备注 AS R94:算法 AS 181 备注:正态性的 W 检验”,1995 年,应用统计学,第 44 卷,DOI:10.2307/2986146

[5]

Phipson B. 和 Smyth, G. K., “置换 p 值永远不应该为零:当置换随机抽取时计算精确 p 值”,统计学在基因和分子生物学中的应用,2010 年,第 9 卷,DOI:10.2202/1544-6115.1585

[6]

潘纳吉奥塔科斯、D. B.“生物医学研究中 p 值的价值”,开放性心血管医学杂志,2008 年,第 2 卷,第 97-99 页,DOI:10.2174/1874192400802010097

示例

假设我们希望从度量中推断某项医学研究中成年男性的体重是否呈正态分布 [2]。体重(磅)记录在以下数组 x 中。

>>> import numpy as np
>>> x = np.array([148, 154, 158, 160, 161, 162, 166, 170, 182, 195, 236])

[1][2] 的正态性检验从计算一个基于观测值和正态分布的预期顺序统计值之间的关系的统计值开始。

>>> from scipy import stats
>>> res = stats.shapiro(x)
>>> res.statistic
0.7888147830963135

对于从正态分布中抽取的样本而言,此统计值往往较高(接近 1)。

通过比较统计值的观测值与空值分布来进行检验,其中空值分布是在这样的空假设下形成的统计值分布,即体重是从正态分布中抽取的。对于此正态性检验而言,空值分布不易准确计算,因此它通常通过蒙特卡罗法来近似,即从正态分布中抽取许多与 x 大小相同的样本,并计算每个样本的统计值。

>>> def statistic(x):
...     # Get only the `shapiro` statistic; ignore its p-value
...     return stats.shapiro(x).statistic
>>> ref = stats.monte_carlo_test(x, stats.norm.rvs, statistic,
...                              alternative='less')
>>> import matplotlib.pyplot as plt
>>> fig, ax = plt.subplots(figsize=(8, 5))
>>> bins = np.linspace(0.65, 1, 50)
>>> def plot(ax):  # we'll reuse this
...     ax.hist(ref.null_distribution, density=True, bins=bins)
...     ax.set_title("Shapiro-Wilk Test Null Distribution \n"
...                  "(Monte Carlo Approximation, 11 Observations)")
...     ax.set_xlabel("statistic")
...     ax.set_ylabel("probability density")
>>> plot(ax)
>>> plt.show()
../../_images/scipy-stats-shapiro-1_00_00.png

此比较通过 p 值来量化,即空值分布中小于或等于统计值的观测值的比例。

>>> fig, ax = plt.subplots(figsize=(8, 5))
>>> plot(ax)
>>> annotation = (f'p-value={res.pvalue:.6f}\n(highlighted area)')
>>> props = dict(facecolor='black', width=1, headwidth=5, headlength=8)
>>> _ = ax.annotate(annotation, (0.75, 0.1), (0.68, 0.7), arrowprops=props)
>>> i_extreme = np.where(bins <= res.statistic)[0]
>>> for i in i_extreme:
...     ax.patches[i].set_color('C1')
>>> plt.xlim(0.65, 0.9)
>>> plt.ylim(0, 4)
>>> plt.show
>>> res.pvalue
0.006703833118081093

如果 p 值“小”,即从正态分布总体中抽取数据产生如此极端统计值概率很低,这可能将被视为反对空假设并支持备选假设的证据:这些体重不是从正态分布中抽取的。请注意

  • 反之不成立;也就是说,该检验不用于为空假设提供证据。

  • 要被视为“小”值的临界值应该是在数据被分析之前选定的 [5],同时考虑两类风险,即假阳性风险(错误地拒绝空假设)和假阴性风险(未能拒绝虚假空假设)。

../../_images/scipy-stats-shapiro-1_01_00.png