原文:SciPy 官方教程:Shapiro–Wilk 正态性检验。作者为 SciPy 文档贡献者。本文依据 2026 年 10 月 05 日读取的 SciPy v1.18.0 在线手册编译;原页未给出首次发表日期。代码和数值输出均来自原文或已标明的编辑补充,本次没有执行模拟。
一次正态性检验,不只是得到一个 p 值。更有用的问题是:如果数据确实来自正态分布,像眼前这么小的统计量有多常见?原教程用 11 项历史体重数据,把这个问题转成可以观察的零分布。数据仅用于统计教学,不用于个人健康判断。

先算观测样本的 Shapiro–Wilk 统计量
原例想检验某研究中成年男性的体重是否偏离正态分布,单位为磅。数据与原论文关联,保留如下:
import numpy as np
from scipy import stats
x = np.array([148, 154, 158, 160, 161, 162, 166, 170, 182, 195, 236])
res = stats.shapiro(x)
res.statistic
原文展示的统计量是 0.7888146948353875。Shapiro–Wilk 统计量建立在观测值与正态分布期望次序统计量的关系上。来自正态总体的样本,其统计量通常较高、接近 1;这里需要关注的是统计量较小的方向,而不是把“越大越异常”当作通用规则。
用同样大小的正态样本构造零分布
零假设是这组观测来自正态分布。零分布则是:在零假设成立时,反复取样并计算该统计量,统计量会形成怎样的分布。原文指出其精确零分布不容易直接计算,因此用蒙特卡洛方法近似:每次生成与 x 一样大的正态样本,再计算同一个统计量。
def statistic(x):
# 只返回 Shapiro–Wilk 统计量,不使用这里计算的 p 值
return stats.shapiro(x).statistic
ref = stats.monte_carlo_test(
x, stats.norm.rvs, statistic, alternative="less"
)
alternative="less" 表示把较小的统计量视为更极端的结果。statistic() 刻意只返回统计量;如果把整个 shapiro 结果对象当作统计量返回,就改变了蒙特卡洛函数的输入约定。原例没有指定随机种子,模拟值和图形会随运行变化。
把零分布画出来
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(8, 5))
bins = np.linspace(0.65, 1, 50)
def plot(ax):
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()
直方图来自 ref.null_distribution,纵轴是概率密度而不是样本数量。每个柱子的高度要与其宽度合起来理解。原例用 0.65 到 1 的 50 个边界值划分柱子,展示的是 11 项观测这一样本量下的参考分布。换一个样本量,不能直接沿用这张零分布解释新的样本。
左尾面积、近似 p 值与模拟 p 值
概念上,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,也就是最初 stats.shapiro(x) 返回的近似 p 值。原文展示的是 0.006703814056502984。它不是 ref.pvalue,不能把这一固定数值写成“本次蒙特卡洛检验得到的结果”。
此外,代码按照柱子的边界进行整柱着色,只是示意左尾区域;有限宽度的柱子无法精确画出统计量所在位置的连续尾部面积。若需要并列报告两种计算方式,可以加上以下编辑补充代码,保留完整含义:
print("Shapiro approximation:", res.pvalue)
print("Monte Carlo estimate:", ref.pvalue)
这两行只是区分来源,没有改变数据和检验方向,也没有在本稿中运行。模拟误差以及具体函数采用的 p 值计算细节,应以实际环境和 monte_carlo_test API 文档为准。
怎样解释这个结果
如果事先选定的显著性阈值把这个 p 值认定为“小”,它说明:在正态总体这一假设下,得到这样极端的统计量并不常见,因此可作为反对零假设的证据。这个概率不是“零假设为真的概率”,也不直接衡量偏离正态分布的实际影响大小。
原文强调两个限制。第一,反过来不成立:没有拒绝零假设,不等于证明总体为正态分布;小样本尤其可能没有足够信息发现偏离。第二,“多小才算小”应在分析数据之前决定,并权衡假阳性与假阴性的风险,不能看到结果后再挑选有利阈值。
代码与版本说明
示例需要 NumPy、SciPy 和 Matplotlib。静态审阅没有在所示代码中发现网络传输、硬编码秘密、命令注入或破坏性文件操作;这不构成无漏洞保证。调用统计函数和绘图函数的实际兼容性、随机结果与性能没有在本次任务中测试。
参考文献与来源
- Shapiro, S. S. & Wilk, M. B. (1965). An analysis of variance test for normality (complete samples). Biometrika, 52, 591–611. DOI:10.2307/2333709。
- NIST/SEMATECH e-Handbook of Statistical Methods, 7.2.1.3, Anderson–Darling and Shapiro–Wilk tests;DOI:10.18434/M32189。
- Phipson, B. & Smyth, G. K. (2010). Permutation P-values Should Never Be Zero: Calculating Exact P-values When Permutations Are Randomly Drawn. Statistical Applications in Genetics and Molecular Biology, 9. DOI:10.2202/1544-6115.1585。
原文版权:© Copyright 2008, The SciPy community。中文编译与原创流程图:未完纪。
SciPy 开源代码许可保留
以下保留 SciPy 官方仓库的 BSD 三条款声明作为相关代码的开源许可说明;不将软件许可自动推定为网页正文许可。
Copyright (c) 2001-2002 Enthought, Inc. 2003, SciPy Developers.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.












暂无评论内容