统计过程控制:质量管理的基石
控制图是统计过程控制 (SPC) 的基石,利用标准差来监控过程随时间的稳定性。它由沃尔特·休哈特在 1920 年代的贝尔实验室开发,能够区分普通原因变异(过程固有的)和特殊原因变异(需要关注的问题)。
控制图的精妙之处在于其简洁性:将测量值按时间绘图,添加基于标准差的控制限,观察是否有数据点或模式发出警告。这种实时监控能在缺陷出现之前就预防问题,而不是事后通过检验才发现。
现代制造业、医疗和服务行业都依赖控制图来维护质量。从需要纳米级精度的半导体制造到医院感染率,SPC 提供了一个通用的过程改进框架。
普通原因与特殊原因
普通原因变异是任何过程中自然存在的、可预期的变异。特殊原因变异表明有什么发生了变化——新操作员、磨损的工具或受污染的材料。控制图帮助你区分这两者。
控制图的类型
不同的数据类型需要不同的控制图。选择正确的图表类型才能确保准确的过程监控:
| 图表类型 | 数据类型 | 应用场景 |
|---|---|---|
| X̄-R(均值-极差图) | 连续型,子组 n≤10 | 制造业测量 |
| X̄-S(均值-标准差图) | 连续型,子组 n>10 | 大批量抽样 |
| I-MR(单值-移动极差图) | 单个测量值 | 昂贵/破坏性检测 |
| p 图 | 不合格品率 | 合格/不合格检验 |
| c 图 | 缺陷计数 | 单位产品的缺陷数 |
对于连续型数据(长度、重量、温度等测量值),X̄-R 图最常用。你收集子组样本,在一个图上绘制平均值 (X̄),在另一个图上绘制极差 (R)。两者结合,同时监控过程的居中性和变异性。
计算控制限
控制限定义了预期变异的边界。它们设定在中心线的 ±3 个标准差处,当过程处于控制状态时捕获 99.73% 的数据点:
控制限
UCL = x̄ + 3σ, CL = x̄, LCL = x̄ - 3σ
对于使用极差法的 X̄ 图,公式变为:
X̄ 图控制限
UCL = X̿ + A₂R̄, LCL = X̿ - A₂R̄
其中 X̿ 是总均值,R̄ 是平均极差,A₂ 是取决于子组大小的常数(例如 n=5 时,A₂ = 0.577)。
控制限 ≠ 规格限
控制限根据你的数据计算得出,反映的是过程实际表现。规格限由客户/工程师设定,反映的是过程应该达到的标准。一个过程可以处于统计控制状态,但仍然产出不合规格的产品。
控制限常数
| n | A₂ | D₃ | D₄ |
|---|---|---|---|
| 2 | 1.880 | 0 | 3.267 |
| 3 | 1.023 | 0 | 2.574 |
| 4 | 0.729 | 0 | 2.282 |
| 5 | 0.577 | 0 | 2.114 |
西电规则:检测问题的信号
超出控制限的单个点并不是唯一的异常信号。西电规则通过将控制图划分为基于标准差的区域来检测更细微的模式:
- C 区:中心线 1σ 范围内
- B 区:距中心线 1σ 到 2σ 之间
- A 区:距中心线 2σ 到 3σ 之间
四条基本规则
1
规则一:单点越界
一个点超出 3σ(A 区或以外)。自然发生的概率仅为 0.27%。
2
规则二:连续 9 点偏向
连续 9 个点落在中心线同一侧。表明过程均值发生了偏移。
3
规则三:连续 6 点趋势
连续 6 个点单调递增或递减。暗示过程漂移或工具磨损。
4
规则四:区域模式
连续 3 个点中有 2 个落在 A 区或以外(同侧)。偏移的早期预警信号。
识别常见模式
有经验的从业者能够识别出指向特定问题的视觉模式:
| 模式 | 表现 | 可能原因 |
|---|---|---|
| 突变 | 水平突然变化 | 新操作员、新批次材料、设备调整 |
| 趋势 | 逐渐向上或向下漂移 | 工具磨损、温度漂移、疲劳 |
| 周期 | 重复的上下波动 | 班次轮换、环境周期、排班变化 |
| 紧贴中心线 | 数据点聚集在中心线附近 | 控制限不正确、数据经过四舍五入或编辑 |
| 分层 | 数据点避开中心线 | 多条生产线混合、多台设备混用 |
Python 实现
创建带有自动规则检查的 X̄-R 控制图:
python
import numpy as np
import matplotlib.pyplot as plt
def create_xbar_chart(data, subgroup_size=5):
"""Create X-bar control chart with control limits."""
# Reshape data into subgroups
n_subgroups = len(data) // subgroup_size
subgroups = data[:n_subgroups * subgroup_size].reshape(n_subgroups, subgroup_size)
# Calculate subgroup means and ranges
xbar = subgroups.mean(axis=1)
R = subgroups.max(axis=1) - subgroups.min(axis=1)
# Control chart constants (for n=5)
A2 = 0.577
D3, D4 = 0, 2.114
# Calculate control limits
xbar_bar = xbar.mean()
R_bar = R.mean()
UCL = xbar_bar + A2 * R_bar
LCL = xbar_bar - A2 * R_bar
# Check for out-of-control points
ooc = (xbar > UCL) | (xbar < LCL)
# Plot
plt.figure(figsize=(12, 5))
plt.plot(xbar, 'b-o', markersize=4)
plt.axhline(xbar_bar, color='g', linestyle='-', label='CL')
plt.axhline(UCL, color='r', linestyle='--', label='UCL')
plt.axhline(LCL, color='r', linestyle='--', label='LCL')
plt.scatter(np.where(ooc)[0], xbar[ooc], color='red', s=100, zorder=5)
plt.xlabel('Subgroup')
plt.ylabel('X-bar')
plt.title('X-bar Control Chart')
plt.legend()
plt.show()
return {'xbar': xbar, 'UCL': UCL, 'LCL': LCL, 'ooc': ooc}
# Example: Monitor a manufacturing process
np.random.seed(42)
# Simulate 100 measurements (20 subgroups of 5)
measurements = np.random.normal(100, 2, 100)
# Add a shift at subgroup 15
measurements[75:] += 3
result = create_xbar_chart(measurements)