4. 控制图数学基础与Python实现
Xbar-R 图由两张图组成:一张监控子组均值的变化,一张监控子组内极差的变化。要让它真正可用,必须先把背后的统计量算准,再用 Python 复现并验证。本节围绕四个核心量展开:子组均值、子组极差、过程标准差估计,以及由此推导出的上下控制限。所有公式都遵循同一约定:控制限以中心线为基准,上下对称或按系数展开,超出限值即视为异常信号。
一、四个基础统计量的定义
设共有 k 个子组,每个子组含 n 个观测值 xi1…xin。子组均值与极差分别为:
- 子组均值:x̄i = (xi1 + … + xin) / n
- 子组极差:Ri = max(xi) − min(xi)
- 总均值(中心线):x̄̄ = Σx̄i / k,即所有子组均值的平均
- 平均极差:R̄ = ΣRi / k
注意 x̄̄ 是“均值的均值”,不是全部原始数据的算术平均;当各子组样本量相等时两者数值相同,但概念上必须区分,否则后续与 R̄ 配套的系数会错位。过程标准差的估计不直接用样本标准差 s,而是借助极差:σ̂ = R̄ / d₂,其中 d₂ 是随子组容量 n 变化的无偏常数。n=5 时 d₂≈2.326,n=4 时 d₂≈2.059,n=3 时 d₂≈1.693。用极差估计标准差的好处是计算简单、对子组内波动敏感,这正是 R 图与 Xbar 图配套使用的原因。
二、控制限公式
Xbar 图的控制限由总均值加减 3 倍均值标准误得到。均值标准误为 σ̂/√n = R̄/(d₂√n),于是:
UCL_x = x̄̄ + 3·R̄/(d₂·√n) = x̄̄ + A₂·R̄
LCL_x = x̄̄ − 3·R̄/(d₂·√n) = x̄̄ − A₂·R̄
CL_x = x̄̄
UCL_R = D₄·R̄
LCL_R = D₃·R̄
CL_R = R̄
其中 A₂ = 3/(d₂√n),D₃、D₄ 由 d₂、d₃ 组合得到。常用系数:n=5 时 A₂=0.577、D₃=0、D₄=2.114;n=4 时 A₂=0.729、D₃=0、D₄=2.282;n=3 时 A₂=1.023、D₃=0、D₄=2.574。当 n≤6 时 D₃ 为 0,意味着 R 图没有下控制限,极差过小不判异,这是正常现象而非程序缺陷。
三、用 numpy / pandas 计算并验证
下面用一组教学示例数据演示完整计算。数据为某灌装线每 30 分钟抽取 5 瓶的净含量(单位 mL,示例假设值),共 10 个子组。
import numpy as np
import pandas as pd
# 示例数据:10 个子组 × 5 个观测
data = np.array([
[502, 498, 505, 500, 495],
[499, 503, 497, 501, 500],
[504, 496, 502, 499, 499],
[500, 501, 498, 503, 498],
[497, 502, 500, 496, 505],
[501, 499, 503, 500, 497],
[498, 504, 496, 502, 500],
[503, 497, 501, 499, 500],
[500, 500, 499, 504, 497],
[496, 503, 502, 498, 501],
])
df = pd.DataFrame(data, columns=[f"x{i+1}" for i in range(5)])
df["xbar"] = df.mean(axis=1)
df["R"] = df.max(axis=1) - df.min(axis=1)
xbar_bar = df["xbar"].mean()
R_bar = df["R"].mean()
n, d2 = 5, 2.326
A2 = 3 / (d2 * np.sqrt(n)) # ≈ 0.577
D3, D4 = 0.0, 2.114
ucl_x, lcl_x = xbar_bar + A2 * R_bar, xbar_bar - A2 * R_bar
ucl_r, lcl_r = D4 * R_bar, D3 * R_bar
print(f"x̄̄={xbar_bar:.3f} R̄={R_bar:.3f}")
print(f"Xbar: UCL={ucl_x:.3f} CL={xbar_bar:.3f} LCL={lcl_x:.3f}")
print(f"R : UCL={ucl_r:.3f} CL={R_bar:.3f} LCL={lcl_r:.3f}")
按示例数据计算,x̄̄ 约为 500.0,R̄ 约为 6.4,A₂ 约 0.577,因此 Xbar 图 UCL≈503.7、LCL≈496.3;R 图 UCL≈13.5、LCL=0。这些数值属于示例推演,实际生产应以真实采集数据重算。
四、交叉验证:三种算法互证
控制限算错往往不易察觉,建议用两条独立路径互证。第一条是“系数法”,即上面的 A₂·R̄;第二条是“标准误法”,直接用 σ̂ = R̄/d₂ 再乘 3/√n。两者应完全一致:
sigma_hat = R_bar / d2
half_width = 3 * sigma_hat / np.sqrt(n)
assert np.isclose(half_width, A2 * R_bar) # 应通过
# 与 pandas 分组聚合结果对照
grouped = df.groupby(df.index // 1).agg(
xbar=("xbar", "mean"), R=("R", "mean"))
print(grouped.head())
若两者出现偏差,常见原因是:子组容量 n 与所用系数不匹配、把总体标准差 s 误当作 σ̂、或对不等长子组直接套用固定系数。不等长子组应改用加权平均或转用 s 图,不能硬套 R 图系数。
五、结果判读与常见陷阱
算出控制限后,判读分两步。先看 R 图:若某子组极差超出 UCL,说明子组内波动异常,此时 Xbar 图的限值不可靠,应先排查 R 图异常点(如混入不同批次、测量误差),剔除或修正后再重算。R 图受控后,再看 Xbar 图:点超出 UCL/LCL 即为均值偏移信号,连续 7 点位于中心线同侧、或呈单调趋势,也属判异规则范畴。
三个高频陷阱值得警惕。其一,用全部数据的标准差 s 代替 σ̂,导致 Xbar 限值偏窄、误报增多;正确做法是 R̄/d₂。其二,子组容量不一致却套用同一组 A₂、D₄,应改用加权 R̄ 或转 s 图。其三,把控制限当作规格限——控制限来自过程自身波动,规格限来自客户要求,两者不可混用。建议在代码中把系数、n、限值一并打印留痕,便于复核与追溯。