一个死在第一周的项目
我带过的一个项目,第一周就搭了梯度提升模型,特征工程做了四十列,回测 WMAPE 6.9%,团队很兴奋。上线一个月,被业务骂下线。
复盘时我做了一件当时觉得多余的事:跑了一遍 Seasonal Naive(抄上周同天)。它的 WMAPE 是 6.4% 。
也就是说,一个月的人力、四十列特征、一套训练流水线,输给了「抄上周同天」这五个字。更糟的是没人知道这件事,因为从头到尾没人跑过基线。从那以后我的规矩是:任何模型动手前,先请四位「笨选手」上场。它们不学习、不训练、甚至有点傻,但它们是考官、是兜底、还是脚手架。
四位笨选手
① 朴素法 Naive:明天 = 今天。
② 季节朴素法 Seasonal Naive:下周六 = 这周六(m 为周期)。
③ 移动平均 MA(k) :未来 = 最近 k 期平均。
④ 漂移法 Drift:照首尾连线的势头继续走。
拿后面反复使用的 8 期周销量 y = [120, 132, 125, 141, 138, 150, 145, 158] 手算第 9 期:
-
Naive:158
-
MA(3):(150+145+158) ÷ 3 = 151.0
-
Drift:斜率 (158−120) ÷ 7 = 5.4286 → 158 + 5.4286 = 163.4286
-
Seasonal Naive(m=4):y(5) = 138
四个答案各不相同——而且没有一个考虑了「周末更高」,除了把 m 取对的 Seasonal Naive。
让数据判卷:第一场
120 天日销(含周季节 + 缓慢上升),前 96 天学习、后 24 天检验:
| 方法 | MAE | WMAPE | Bias | MASE |
|---|---|---|---|---|
| Naive | 34.33 | 5.94% | −5.94% | 1.42 |
| Seasonal Naive | 16.64 | 2.88% | −1.85% | 0.69 |
| MA(7) | 18.63 | 3.22% | −2.34% | 0.77 |
| Drift | 29.36 | 5.08% | −5.05% | 1.22 |
三个观察,每个都值钱:
- Seasonal Naive 赢得干净(MASE 0.69)。这段数据的主要规律是「每周重复」,只有它显式用了周期。你的模型打不赢它,说明你连日历都没用好。
- Naive 和 Drift 的 MASE > 1:在有周季节的日销上,「抄昨天」「抄趋势」都不如「抄上周同天」。
- 所有方法 Bias 都为负:数据在涨,回头看的方法必然低估。这个 −1.85% 就是第 6 篇 Holt 要解决的问题。
让数据判卷:第二场(冠军会换人)
别把第一场的结论当真理。换一段无周期、强趋势的数据 y = [100, 110, 120, 130, 140, 150, 160, 170],第 9 期真值 180:
| 方法 | 预测 | 误差 |
|---|---|---|
| Naive | 170 | −10 |
| MA(3) | (150+160+170)÷3 = 160 | −20 |
| Seasonal Naive(m=4) | y(5) = 140 | −40 |
| Drift | 170 + (170−100)÷7 = 180 | 0 |
Drift 满分,而上一场的冠军 Seasonal Naive 这次错 40。 结论:基线没有全能选手,数据形态决定冠军。所以「最优基线」必须按 SKU 逐个算、定期重算,而不是全公司统一指定一个。
每位选手的擅长与致命伤
| 基线 | 擅长 | 致命伤 |
|---|---|---|
| Naive | 高频平稳序列的 1 步预测 | 完全忽略季节与趋势 |
| Seasonal Naive | 强周期、水平稳定 | 水平突变时反应慢一整个周期 |
| MA(k) | 噪声大、无周期 | 硬截断 + 等权(第 5 篇会修) |
| Drift | 稳定线性趋势 | 趋势拐弯时冲过头 |
基线还能组合:一个手算示例
两个基线预测 100 和 120,实际 108:单用误差分别 8 和 12;简单平均 110,误差 2。当两个基线的误差方向相反时,组合几乎总是赢。
但它有失效条件:若两基线同向偏(都低估),组合救不了你。实务做法:按过去 8 周误差倒数加权(误差小的权重大),并监控组合与最优单基线的差——差值持续为负才保留组合,否则退回单基线(少一个要维护的东西)。
上线门槛怎么定:别只说「好 10%」
「比基线好 10% 才上线」是常用规则,但还差一步:这个「好」是真的还是运气? 用配对比较的直觉版 t 检验:
取 24 折回测,每折记录「基线误差 − 模型误差」的差值 d。设 mean(d) = 1.8、sd(d) = 4.2:
-
标准误 se = 4.2 ÷ √24 = 0.857
-
t = 1.8 ÷ 0.857 = 2.10
t > 2 大致对应「95% 把握认为模型真的更好」。若 mean(d) = 1.8 但 sd = 9,则 t = 0.98——改善存在但不显著,先别上线,加折数或改特征。这一步能挡住一半「回测漂亮、上线翻车」的事故。
兜底切换:笨选手的第二身份
每个 SKU 永远保留一列基线预测。切换规则写成决策表,避免临场拍脑袋:
| 触发条件 | 动作 |
|---|---|
| 模型任务失败 / 延迟超阈值 | 自动切基线,告警 |
| 新 SKU 历史 < 2 个周期 | 默认基线 + 类比修正(第 13 篇) |
| 滚动 14 天 MASE > 1 | 切基线 + 立项归因 |
| 大促爆发日 | 切大促专用模型(第 9 篇),基线仅作对照 |
| 数据还原口径变更当周 | 切基线,避免口径污染评估 |
读者问答
Q1:基线这么强,是不是说明机器学习没用? 不是。基线强在「抓住主要规律且零维护」,弱在「不能吃外部变量、不能跨 SKU 借知识、不能给分位数」。第 8~13 篇的每一篇都在补基线补不了的缺口。正确心态:基线是地板,不是天花板。
Q2:MASE 的分母用哪个基线? 用该 SKU 的最优基线(通常是 Seasonal Naive)。用弱基线做分母会让 MASE 虚假地小,门槛形同虚设。
Q3:基线需要调参吗(比如 MA 的 k)? 需要,但只在回测上调一次并季度复核:k 太小噪声大,k 太大反应慢。经验起点:日销 k=7,周销 k=4,月销 k=3。
实操清单
- 为每个 SKU 跑四个基线的滚动回测,记录最优基线及其 WMAPE,落库。
- 上线门槛 = 相对最优基线改善 ≥ 10% 且 配对 t > 2,两条都写进验收标准。
- 预测表加 baseline 列与 model_version 列,兜底切换自动化并告警。
- 每季度重算最优基线——业务结构变了,冠军会换人。
- 把「基线对照」放进一页纸误差报告(第 3 篇模板),让团队永远知道地板在哪。
带走三句话:基线是考官、兜底、脚手架三重身份;数据形态决定冠军,最优基线要按 SKU 逐个算;上线门槛 = 相对改善 ≥10% 且配对 t > 2,缺一不可。
下一篇:移动平均的硬截断让人不舒服——指数平滑用一个递推公式解决它,我会把权重展开和半衰期公式完整推给你。