2. 微生物检验结果的可视化趋势监控

为什么微生物趋势监控不能只画折线

微生物检验结果(菌落总数、大肠菌群、霉菌酵母等)具有批次间波动大、检出限截断、结果呈对数分布的特点。如果只是把多批次结果连成折线,很容易把正常的抽样波动误判为异常,也容易漏掉"连续多批缓慢抬升"这种真正危险的趋势。因此本节的核心是:先定义QC判定规则,再让可视化去承载这些规则——警戒线、行动线、连续超限计数、趋势斜率,都是规则的可视化投影。

本节采用一张"产品线 × 采样点"的监控矩阵作为组织骨架:每条产品线在每个采样点(原料、半成品、成品、环境涂抹)各有一条趋势通道,通道上叠加警戒线(WL)与行动线(AL),并用状态色标出"正常 / 关注 / 连续超限 / 异常波动"四类判定结果。

微生物趋势监控矩阵:产品线 × 采样点 × QC判定规则 纵轴=产品线,横轴=采样点;每格为一条趋势通道,叠加警戒线WL与行动线AL 原料 半成品 成品 环境涂抹 A线 乳制品 B线 烘焙类 C线 调味酱 WL AL 正常 关注·逼近WL 连续超限·触发AL 正常 正常 异常波动·锯齿 正常 关注·逼近WL 正常 正常 连续超限·触发AL 正常 QC判定规则 → 可视化映射 警戒线 WL:单批接近限值,触发"关注" 行动线 AL:连续2批≥WL 或 单批≥AL,触发"连续超限" 异常波动:相邻批次跳变幅度超过设定阈值(锯齿判定) 正常 关注 连续超限 异常波动

把判定规则写成可执行的监控逻辑

上图的关键不是"画得好看",而是每个颜色都对应一条可复算的规则。下面用一段可直接运行的 Python 代码,把"警戒线 / 行动线 / 连续超限 / 异常波动"四条规则落到多批次数据上,输出每个"产品线-采样点"通道的判定状态。示例数据为教学构造,非实测结果。

import pandas as pd

# 教学示例数据:产品线、采样点、批次、菌落总数(log10 CFU/g)
rows = [
    ("A线","成品","B01",2.1),("A线","成品","B02",2.6),("A线","成品","B03",2.9),
    ("A线","成品","B04",3.1),("A线","成品","B05",3.3),
    ("B线","半成品","B01",2.0),("B线","半成品","B02",3.2),("B线","半成品","B03",2.1),
    ("B线","半成品","B04",3.3),("B线","半成品","B05",2.2),
    ("C线","成品","B01",2.4),("C线","成品","B02",2.8),("C线","成品","B03",3.0),
    ("C线","成品","B04",3.2),("C线","成品","B05",3.4),
]
df = pd.DataFrame(rows, columns=["line","point","batch","log_cfu"])

# 规则参数(按产品线/采样点分别设定,此处示例统一值)
WL, AL = 3.0, 3.5          # 警戒线、行动线(log10 CFU/g)
JUMP = 0.8                 # 相邻批次跳变阈值
CONSEC = 2                 # 连续达到WL的批次数

def judge(g):
    g = g.sort_values("batch").reset_index(drop=True)
    v = g["log_cfu"].tolist()
    flags = []
    for i, x in enumerate(v):
        if x >= AL:
            flags.append("连续超限")
        elif i >= CONSEC-1 and all(y >= WL for y in v[i-CONSEC+1:i+1]):
            flags.append("连续超限")
        elif i >= 1 and abs(x - v[i-1]) >= JUMP:
            flags.append("异常波动")
        elif x >= WL:
            flags.append("关注")
        else:
            flags.append("正常")
    g["判定"] = flags
    return g

result = df.groupby(["line","point"], group_keys=False).apply(judge)
print(result.to_string(index=False))

运行后每个通道会得到逐批判定。以 A线-成品 为例:B03 达到 2.9(未到 WL,正常),B04 为 3.1(≥WL,关注),B05 为 3.3(≥WL 且前一批也≥WL,满足连续 2 批,判为"连续超限")。B线-半成品 则在 2.0→3.2→2.1→3.3→2.2 之间反复跳变,跳变幅度均 ≥0.8,判为"异常波动"而非"连续超限"——这正是趋势图必须区分两类异常的原因:前者是水平漂移,后者是过程不稳定。

判定顺序很重要:先判"单批≥AL",再判"连续≥WL",再判"跳变",最后才落到"关注/正常"。顺序颠倒会让连续超限被误标为异常波动。

趋势图与判定结果的联动检查

把上面的判定结果回填到监控矩阵后,需要做一次"图-数一致性"核对,避免可视化误导:

  • 线位核对:WL、AL 必须按产品线/采样点分别设定,不能全厂一条线。乳制品成品与环境涂抹的限值差异很大,混用会让判定失真。
  • 截断处理:微生物结果常出现"<10"这类检出限截断值,绘图时应统一按检出限的一半或规定替代值处理,并在图上标注,不能直接当 0 画。
  • 批次连续性:连续超限依赖批次顺序,若中间有停产或未采样批次,需在趋势线上断开,不能跨空档累计"连续"。
  • 颜色只表达判定:正常/关注/连续超限/异常波动四色必须与规则输出一一对应,不允许人工"看着像"改色。
判定状态触发条件(示例参数)可视化表现QC动作
正常所有批次 < WL绿色折线,位于WL下方维持监控频率
关注单批 ≥ WL 且 < AL橙色折线,逼近WL虚线加采平行样,核查同批原料
连续超限连续2批 ≥ WL,或单批 ≥ AL红色折线,穿越AL虚线隔离批次,启动偏差调查
异常波动相邻批次跳变 ≥ 0.8 log深黄锯齿折线排查采样、稀释、培养环节
警戒线与行动线不是固定常数。应根据历史基线(如近 30 批的均值与标准差)按产品线和采样点分别计算,并定期复核;直接用行业通用限值替代内控线,会让趋势监控失去早期预警能力。

完成上述步骤后,本节的可交付成果是一张"产品线×采样点"监控矩阵加一份逐批判定表:矩阵用于快速定位哪条通道需要干预,判定表用于追溯每一批的规则命中依据。两者共同构成微生物趋势监控的可视化闭环。