1. 课程导入与场景锚定

在食品生产线上,一批次产品的净含量、酸度、菌落总数或包装密封强度,往往不会因为“合格”二字就自动稳定。质量控制的真正难点不在于抽检一次是否达标,而在于判断过程是否持续受控、波动是否属于正常随机误差、异常是偶发还是已经形成趋势。控制图(Control Chart)正是把这种判断从经验直觉变成可复核证据的工具:它用中心线(CL)、上控制限(UCL)和下控制限(LCL)划出过程“正常波动”的边界,再按时间顺序描点,让越界、连续偏移、趋势等信号显性化。

对食品行业而言,控制图的价值有三层。第一层是合规与追溯:净含量、微生物、理化指标等关键控制点需要留痕,控制图天然带有时间序列和判异记录。第二层是过程改进:仅看批合格率会掩盖波动,控制图能区分“普通原因”和“特殊原因”,避免对随机波动过度调整。第三层是成本:越早发现灌装量漂移、杀菌温度异常或封口不良,越能减少整批报废与召回风险。因此本课程不把控制图当作统计课习题,而是当作一条从数据到判异、从判异到行动的工程链路。

常见控制图类型与选用逻辑

控制图按数据类型分为计量型和计数型两大类。计量型数据是连续测量值,如净含量(g)、pH值、杀菌温度(℃),常用Xbar-R图(子组样本量较小,通常2~9)和Xbar-S图(子组样本量较大,通常≥10,用标准差替代极差)。计数型数据是合格/不合格或缺陷个数,常用p图(不合格品率,子组样本量可变)、np图(不合格品数,样本量固定)、c图(单位产品缺陷数,样本量固定)、u图(单位产品缺陷率,样本量可变)。

选图的关键不是背名称,而是先问三个问题:指标是“测量出来的”还是“数出来的”?每次抽样的子组大小是否固定?关注的是“不合格品”还是“缺陷点”?例如某乳品厂每30分钟抽5盒测净含量,属于计量型、子组n=5,应选Xbar-R;若每批抽200袋统计胀袋数,属于计数型、样本量固定,应选np图;若不同批次抽检量不同,则用p图或u图。选错图型会让控制限失去统计意义,这是初学者最常见的错误。

食品质量控制图:类型选择与Python自动化链路 第一步:判断数据类型 计量型(连续测量) 净含量、pH、温度、水分 计数型(合格/缺陷) 胀袋数、菌落超标批、异物点 子组大小是否固定? 固定 → R图 / S图 / np / c 可变 → p图 / u图 关注缺陷点 → c / u 常见误选提醒 n=5 却用Xbar-S 样本量变化仍用np图 把缺陷数当不合格品数 第二步:匹配控制图 Xbar-R 图 子组 n=2~9,均值+极差 Xbar-S 图 子组 n≥10,均值+标准差 p 图 / np 图 不合格品率 / 不合格品数 c 图 / u 图 缺陷数 / 单位缺陷率 控制限计算要点 CL = 子组统计量的均值 UCL/LCL = CL ± 3σ(或A2·Rbar等) σ 由 Rbar/d2 或 Sbar/c4 估计 判异:越界、连续7点同侧、趋势等 第三步:Python自动生成 ① 读取数据 pandas.read_csv / read_excel ② 清洗与分组 时间排序、子组编号、缺失处理 ③ 计算统计量 均值、极差、标准差、p、u ④ 计算控制限 CL / UCL / LCL 与判异规则 ⑤ 绘图输出 matplotlib 折线+控制限+标记 ⑥ 判异与留档 导出PNG/PDF、异常点清单 输出物:控制图 + 判异记录 可直接嵌入质量报告或批次档案

Python自动生成的整体流程

把控制图做成可重复的自动化产物,核心是把“统计计算”和“绘图呈现”拆开。一个稳健的流程通常包含六步:读取数据、清洗与子组划分、计算子组统计量、计算控制限与判异、绘图、输出留档。以Xbar-R图为例,假设某饮料厂每30分钟抽5瓶测净含量(单位mL,目标500mL),数据表包含“时间、子组号、5个测量值”字段。读取后先按时间排序,确保描点顺序与生产顺序一致;再按子组号聚合,得到每个子组的均值x̄和极差R。

控制限的计算不是拍脑袋定±3mL,而是由过程自身波动估计。Xbar图的控制限为:CL=x̄̄(各子组均值的均值),UCL=x̄̄+A₂·R̄,LCL=x̄̄−A₂·R̄;R图的控制限为:CL=R̄,UCL=D₄·R̄,LCL=D₃·R̄。其中A₂、D₃、D₄是按子组大小n查表的常数,n=5时A₂≈0.577、D₃≈0、D₄≈2.114。这里必须强调:常数来自统计表,不能随意替换;若子组n=5却套用n=10的常数,控制限会明显失真。

import pandas as pd
import matplotlib.pyplot as plt

# 示例数据:每子组5个净含量测量值(mL),仅用于演示
df = pd.read_csv("net_content.csv")   # 字段:time, subgroup, v1..v5
vals = df[["v1","v2","v3","v4","v5"]]
df["xbar"] = vals.mean(axis=1)
df["R"]    = vals.max(axis=1) - vals.min(axis=1)

xbar_bar = df["xbar"].mean()
R_bar    = df["R"].mean()
A2, D3, D4 = 0.577, 0.0, 2.114      # n=5 对应常数

ucl_x, lcl_x = xbar_bar + A2*R_bar, xbar_bar - A2*R_bar
ucl_r, lcl_r = D4*R_bar, D3*R_bar

fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(9, 6), sharex=True)
ax1.plot(df["subgroup"], df["xbar"], marker="o", color="#2b7a66")
ax1.axhline(xbar_bar, color="#333", ls="--")
ax1.axhline(ucl_x, color="#c0392b", ls=":")
ax1.axhline(lcl_x, color="#c0392b", ls=":")
ax1.set_ylabel("子组均值 x̄ (mL)")
ax2.plot(df["subgroup"], df["R"], marker="s", color="#a35a1c")
ax2.axhline(R_bar, color="#333", ls="--")
ax2.axhline(ucl_r, color="#c0392b", ls=":")
ax2.set_ylabel("极差 R (mL)")
ax2.set_xlabel("子组号")
plt.tight_layout()
plt.savefig("xbar_r_chart.png", dpi=150)

运行后应重点观察三件事:第一,是否有子组均值或极差越过红色控制限;第二,是否出现连续7点位于中心线同一侧、连续上升或下降等非随机模式;第三,R图是否先于Xbar图报警——极差变大往往意味着设备或操作出现波动,是均值漂移的前兆。若发现越界点,不能直接删除数据,而应回查该时段原料批次、灌装头、杀菌记录,确认是特殊原因后再决定是否剔除并重算控制限。这正是控制图“判异—追溯—处置”的闭环价值。

教学示例中的500mL目标值、n=5、A₂=0.577等参数均为演示用合理假设,实际项目应依据产品标准、抽样方案和统计常数表确定,并以真实数据运行结果为准。

本课程后续将围绕这条链路逐层展开:如何用pandas组织食品质量数据、如何按图型选择正确的统计量与常数、如何用matplotlib把控制限和异常点画清楚、如何把判异规则写成可复用函数,以及如何把单张图扩展为按产品、按产线批量生成的报告。掌握这条链路后,控制图就不再是事后补做的图表,而是嵌入日常质量管理的自动预警工具。