事故一时间线
先把那晚的事完整还原一遍,因为后面所有道理都从这张时间表里长出来:
| 时间 | 发生了什么 |
|---|---|
| 21:47 | 运营群截图:SKU-10086 库存 0、在途 0,客服话术改「补货中」 |
| 21:52 | 计划同事甩报表:模型未来 7 天日均预测 520 件,「我们就是按 520 备的」 |
| 22:10 | 拉出近 30 天销量:日均 512 件——模型没算错,它忠实地预测了它看到的东西 |
| 22:31 | 有人问了一句:「这 30 天里,有几天是断货的?」 |
| 22:34 | 答案:6 天。那 6 天销量分别是 0、0、0、210、0、0 |
| 22:40 | 会议室安静了。真实日均需求不是 512,是 512×30 ÷ 24 ≈ 640 |
| 次日 09:00 | 复盘结论:模型低估约 20%,备货跟着低估,断货是系统自己喂出来的 |
注意 22:10 到 22:34 之间的那四分钟:整个项目的认知被一句提问翻转了。问题不在模型,在数据的定义。
你看到的销量,是需求和库存里较小的那个
销量 = min(需求, 可供货量)。这句话值得抄在工位上。
-
缺货那几天,销量是 0——但需求不是 0,顾客想买,只是没买到;
-
大促限流那几个小时,销量被系统掐住,需求在排队;
-
陈列位被砍、页面下架、区域停售,销量都会「凭空消失」。
我画过一张对照图,把真实需求和系统里唯一能看到的销量放在一起:
红色阴影就是被库存吃掉的部分。这段 60 天数据:真实需求合计 14024.0 件,观测销量 10682.5 件,被截断 3341.5 件——系统性低估 23.83% 。三段缺货(完全断货、只满足 35%、再次断货)在销量表里看起来只是「那几天生意不好」。
缺货螺旋:两轮推演给你看
为什么说这是「自我实现」的?用一个极简推演,真需求恒为每天 100 件:
| 周 | 发生了什么 | 模型看到的周销量 | 下周备货 | 实际卖出 |
|---|---|---|---|---|
| 第 1 周 | 一切正常 | 700 | 700 | 700 |
| 第 2 周 | 一切正常 | 700 | 700 | 700 |
| 第 3 周 | 供应商迟到 3 天(外部事故) | 400 | — | 400 |
| 第 4 周 | 模型学会「现在一周卖 400」 | 400 | 400 | 400(需求 700,缺 300) |
| 第 5 周 | 模型确认「果然只卖 400」 | 400 | 400 | 400 |
| … | 永久锁定在 400/周 | 400 | 400 | 400 |
一次性的外部事故,经过「销量截断 → 模型学习 → 备货跟随 → 再次截断」的闭环,变成了永久性低估 43% 。没有任何人会察觉,因为报表上「预测准确率」一直很高——它准确地预测了自己造成的缺货。
这就是事故一的完整机理。模型不坏,坏的是闭环里没人校验「销量是否等于需求」。
销量还原:三种做法,各有适用场景
建模前的第一道工序,是把被截断的销量补回去。三种做法:
| 方法 | 做法 | 适用 | 坑 |
|---|---|---|---|
| 速率法 | 缺货前 k 天日均 × 缺货时长 | 缺货短、需求平稳 | k 取太大会把趋势抹平 |
| 同期法 | 上周同天销量 × 周环比系数 | 有强周季节 | 上周同天若也缺货,误差叠加 |
| 模型法 | 用未缺货时段拟合的模型反推缺货期 | 缺货长、有促销干扰 | 模型本身有偏时会放大偏 |
手算(速率法) :缺货 3 天,缺货前 7 天日均 820 件 → 补 3 × 820 = 2460 件。
手算(同期法) :缺货的三天对应上周同三天销量 790 / 810 / 830,近四周周环比均值 1.02 → 还原为 790×1.02 = 806、810×1.02 = 826、830×1.02 = 847,合计 2479 件。
两种方法差 19 件(0.8%),可以接受;如果差超过 10%,说明需求在这几天有结构性变化,得查促销和流量。还原值要落库并打标(哪几天是还原的、用的哪种方法),否则三个月后没人说得清哪些数字是观测、哪些是估计。
「帮我预测一下销量」是一句无法执行的话
接过需求的人都知道这句话有多坑。可执行的预测任务必须钉死四个维度,下面是我开会时逐条问的清单:
对象与粒度
-
预测到 SKU 还是 SPU?颜色尺码算不算独立对象?
-
空间到全国、分仓、还是分门店?跨仓调拨算不算需求?
-
线上线下分开吗?直播渠道单独建模吗?
时间窗与节奏
-
看多远:7 天补货、21 天采购、还是 13 周计划?预测窗口必须 ≥ 决策提前期(第 14 篇会算这笔账)。
-
日粒度还是周粒度?聚合会丢掉什么、换来什么?
口径
-
预测需求还是销量?(读完本篇,答案永远是需求)
-
含退货吗?含赠品发出吗?含内部领用和调拨吗?
-
缺货期用还原值还是观测值?(还原值,且打标)
责任与考核
-
这个预测给谁用?补货、排产、还是财务预算?三者容忍的误差方向完全不同。
-
考核用什么指标、按什么分层?(第 3、15 篇)
-
谁有权改预测?改了怎么留痕?(第 15 篇)
-
出错时归因的第一责任人是谁?
问完这 12 个问题,项目成功率至少翻倍——因为它们把「预测」从一个模糊愿望变成了一个可验收的合同。
这里还有个绕不开的张力:决策发生在最细的粒度,信息量在最粗的粒度最充足。单仓单 SKU 明天卖多少鬼才知道,但全国品类月销稳得很。工业界解法:粗粒度预测准,再层级调和拆回去(第 13 篇)。
预测的产出是三样东西,不是一个数
初学者交差:「明天卖 523 件。」成熟的系统交一张预测卡片:
| 字段 | 值 | 给谁用 |
|---|---|---|
| 点预测 P50 | 523 | 报表、例会沟通 |
| P10 / P25 | 452 / 486 | 清仓与停产判断 |
| P75 / P90 | 566 / 611 | 大促备货、长提前期采购 |
| 理由分解 | 基线 400 + 周末 60 + 促销 80 − 透支回补 17 | 归因、干预、信任 |
| 基线对照 | Seasonal Naive = 508(本模型 +2.9%) | 上线门槛、兜底切换 |
| 置信说明 | 近 28 天 P10~P90 覆盖率 81%(名义 80%) | 校准体检 |
第三行「理由」最容易被砍掉,也最致命:没有理由的预测,出错时无法归因,于是永远改不对;业务也不敢信一个说不出为什么的数字。
准不准,先看你亏得起哪种错
回到煎饼摊。老张的决策只取决于两个数字的比值:少摊一份亏 5 块(Cu),多摊一份亏 3 块(Co)。Cu > Co → 偏向多摊。换成当天必须销毁的鲜切花,结论立刻反转。
手算两个真实行业的对照,感受这个比值的力量:
| 行业 | 售价 | 成本 | 季末残值 | Cu = 售价−成本 | Co = 成本−残值 | 临界分位数 Cu÷(Cu+Co) | 该备到 |
|---|---|---|---|---|---|---|---|
| 生鲜叶菜 | 10 | 6 | 1 | 4 | 5 | 0.444 | 均值略低(z ≈ −0.14) |
| 3C 配件 | 100 | 40 | 30 | 60 | 10 | 0.857 | 均值 + 1.07σ |
同一套预测系统,在叶菜上应该「宁可少备」,在 3C 配件上应该「宁可多备」——差别不在预测精度,在代价结构。这就是第 14 篇报童模型的全部输入,也是事故二那 240 万亏损的真正原因:没人做这张表。
预测误差本身不花钱,花钱的是「误差 × 代价结构」。 所以下次有人问「预测做到多少准确率才算好」,正确回答是反问:你们少备一件亏多少、多备一件亏多少?
读者问答:三个最常见的反驳
Q1:「缺货期很少,还原不还原影响不大吧?」 算一笔账:若某 SKU 一年缺货 12 天、日均 800 件,不还原就低估约 9600 件/年,占年销(约 29 万)的 3.3%。听起来小?这 3.3% 是系统性、单方向的,它会直接变成安全库存该加却没加的部分(第 14 篇:σ 低估 → SS 低估 → 缺货概率上升)。方向性偏差比随机误差贵得多。
Q2:「还原值是我们估的,拿估的数据训练不会引入新偏差吗?」 会,但两害相权:观测销量的偏差是向下截断(必然低估),还原值的偏差是估计误差(可双向、可度量、可迭代)。前者是系统性的坑,后者是可控的噪声。而且还原值打标后,你可以随时对比两种口径下模型的差异。
Q3:「需求根本观测不到,谈『真实需求』是不是伪命题?」 需求确实不可直接观测,但「被截断的部分」可以估计——缺货前的需求速率、排队数据、加购未支付、客服询单,都是证据链。工程上我们不追求「真值」,追求偏差方向已知且可修正:这就够了。
实操清单:本周就能做的六件事
- 拉出近 90 天「库存 = 0 或售罄率 > 95%」的天数清单,按 SKU 排序——你会第一次看见截断的规模。
- 对 Top 20 缺货 SKU 用速率法做还原,对比还原前后的日均需求差,把差值换算成年化金额。
- 在事实表加三列:stockout_flag、stockout_hours、demand_qty(还原值),并写还原方法的单元测试。
- 把「预测需求还是销量」写进需求文档第一行,让业务签字。
- 为每个 SKU 建 Cu/Co 卡片(售价、成本、残值、缺货流失估计),算出临界分位数。
- 在周报里加一列「还原口径 vs 观测口径的预测差异」,让团队对截断保持痛感。
带走三句话:销量 = min(需求, 可供货量),建模前先还原并打标;缺货螺旋会把一次性事故变成永久低估;Cu÷(Cu+Co) 决定你该备到哪个分位数,与精度无关。
下一篇:数据洗干净了,接下来看懂它的形状——把一条乱糟糟的曲线拆成四块积木,我会证明为什么「中心化移动平均」能恰好抹掉季节。