4. 累计采剥量偏差曲线构建与阈值判定

偏差曲线的构造口径

累计采剥量偏差曲线用于回答两个问题:偏差在什么时刻开始出现,以及偏差持续了多久、量级多大。构造时统一采用“实际累计量减计划累计量”的符号约定:正值表示超前,负值表示滞后。为避免单日波动掩盖趋势,曲线以对齐后的日累计序列为横轴,纵轴为累计偏差量(万m³),同时保留偏差率(累计偏差 ÷ 计划累计量)作为辅助判据。

设第 i 日计划累计量为 Pi、实际累计量为 Ai,则累计偏差 Di = Ai − Pi,偏差率 Ri = Di / Pi。阈值判定采用“量级 + 持续时长”双条件:单日越限只记为疑似事件,连续越限达到设定天数才升级为正式预警事件,从而过滤掉单班停产、临时检修造成的短时抖动。

分级预警阈值设定

阈值需结合矿山月度计划量与生产节奏确定。以下为某露天矿(月计划采剥量 300 万m³)的示例阈值配置,可按实际规模等比调整:

预警级别累计偏差量 |D|偏差率 |R|持续时长处置要求
蓝色(关注)≥ 3 万m³≥ 2%连续 2 日记录事件,班中核查
黄色(预警)≥ 8 万m³≥ 5%连续 3 日调度会通报,制定追赶措施
橙色(严重)≥ 15 万m³≥ 8%连续 3 日调整设备与台阶配置
红色(紧急)≥ 25 万m³≥ 12%连续 2 日启动专项纠偏,重排计划

量级与偏差率取“或”关系:任一条件满足即触发对应级别,但必须同时满足持续时长条件才计入事件清单。红色级别因后果严重,持续时长门槛适当放宽。

累计偏差曲线 D=A−P 与分级阈值带(示例:月计划300万m³) 0 +3 +8 +15 −15 −8 −3 生产日(对齐后日累计序列) 累计偏差 D(万m³) D1 D5 D9 D13 D17 D21 D25 D30 D9 越限起点 D13 橙色 D17 红色 持续滞后区间 D9–D21(13日) D25 起偏差收窄 累计偏差曲线 红色阈值 ±15 橙/黄阈值

偏差事件识别与清单输出

基于曲线与阈值带,按“越限起点—级别升级—恢复点”三段式扫描,可自动提取偏差事件。以下 Python 示例对日累计序列执行扫描,输出事件清单(含起始日、结束日、持续天数、峰值偏差、最高级别)。示例数据为教学构造,用于演示判定逻辑。

import pandas as pd

# 示例:对齐后的日累计序列(万m³),D1~D30
days = list(range(1, 31))
plan_cum = [10 * d for d in days]          # 计划日累计 10 万m³/日
actual_cum = [10, 20, 30, 40, 48, 56, 64, 72, 78, 84,
              90, 96, 102, 108, 114, 120, 126, 132, 138, 144,
              150, 156, 162, 168, 174, 180, 186, 192, 198, 204]
df = pd.DataFrame({"day": days, "P": plan_cum, "A": actual_cum})
df["D"] = df["A"] - df["P"]
df["R"] = df["D"] / df["P"]

# 分级阈值:级别, 量级阈值, 偏差率阈值, 持续天数
levels = [
    ("红色", 25, 0.12, 2),
    ("橙色", 15, 0.08, 3),
    ("黄色", 8,  0.05, 3),
    ("蓝色", 3,  0.02, 2),
]

def level_of(row):
    for name, dv, rv, _ in levels:
        if abs(row["D"]) >= dv or abs(row["R"]) >= rv:
            return name
    return None

df["lvl"] = df.apply(level_of, axis=1)

# 扫描连续越限区间
events, start, cur = [], None, None
for _, row in df.iterrows():
    if row["lvl"] is not None:
        if start is None:
            start, cur = row["day"], row["lvl"]
        else:
            order = [l[0] for l in levels]
            if order.index(row["lvl"]) < order.index(cur):
                cur = row["lvl"]
    else:
        if start is not None:
            events.append((start, row["day"] - 1, cur))
            start, cur = None, None
if start is not None:
    events.append((start, df["day"].iloc[-1], cur))

# 按持续时长门槛过滤并输出清单
min_days = {"红色": 2, "橙色": 3, "黄色": 3, "蓝色": 2}
rows = []
for s, e, lv in events:
    dur = e - s + 1
    if dur >= min_days[lv]:
        seg = df[(df["day"] >= s) & (df["day"] <= e)]
        peak = seg.loc[seg["D"].abs().idxmax()]
        rows.append({"起始日": s, "结束日": e, "持续天数": dur,
                     "最高级别": lv, "峰值偏差": peak["D"],
                     "峰值偏差率": round(peak["R"], 3)})
print(pd.DataFrame(rows).to_string(index=False))

示例数据下,D9 起实际累计量开始低于计划,D17 偏差达到 −34 万m³(偏差率约 −12.6%),触发红色级别;D25 后偏差逐步收窄。扫描结果应输出一条持续区间事件,起始日 D9、结束日 D21、持续 13 日、最高级别红色、峰值偏差 −34 万m³。若实际数据中某日短暂恢复至阈值内,扫描会将其切分为两段事件,这正是“持续时长”条件需要配合“允许中断天数”参数使用的原因——工程上可设置 1 日容差,避免把单日回补误判为事件结束。

阈值不是固定值:当月计划量调整、台阶剥离与采矿比例变化时,应按比例重算量级阈值,并复核偏差率阈值是否仍与历史正常波动区间匹配。建议每季度用近 3 个月数据回测一次,统计误报率与漏报率。
偏差曲线只反映总量关系,不能直接说明偏差来自哪个台阶或哪个采区。识别出事件后,需进一步按台阶、采区分解偏差来源,避免把总量偏差简单归因于单一环节。