多SKU层次化预测:从单品到品类,如何保持预测一致性?
单品预测结果加起来不等于品类总预测?品类总预测拆分后与单品预测矛盾?这是层次化预测(Hierarchical Forecasting)的经典难题。本文介绍两种主流解法:自上而下、自下而上,以及最佳实践——最优组合预测,附完整代码。
一、问题定义:为什么预测会不一致?
假设你经营一家便利店,有三个维度:
· 单品层(SKU):纯牛奶、酸奶、果汁…
· 品类层:乳制品、饮料、零食…
· 总店层:全店销售额
你分别训练了三个模型:
· 单品模型预测纯牛奶明天 100 件
· 品类模型预测乳制品明天 250 件
· 总店模型预测全店明天 2000 元
但乳制品品类下除了纯牛奶还有酸奶(预测 120 件)、奶酪(预测 30 件),加起来 250 件,与品类预测一致吗?不一定。更常见的情况是:单品预测之和 ≠ 品类预测。这种不一致会带来决策困境——到底该相信哪个预测?
业务影响:
· 如果按单品预测备货,可能导致品类总库存与预期不符。
· 如果按品类预测分配预算,单品层面的计划可能失衡。
二、三种经典策略
2.1 自下而上(Bottom-Up)
做法:只训练单品模型,品类和总店预测由单品汇总得到。
优点:简单、一致、单品粒度最细。
缺点:单品模型误差会向上累积,导致高层预测不稳定。
2.2 自上而下(Top-Down)
做法:只训练总店模型,然后按历史比例(或预测比例)拆分到品类、单品。
优点:高层预测更稳健(因为波动小)。
缺点:丢失单品个性,对促销等事件的响应迟钝。
2.3 最优组合预测(Optimal Combination)
做法:同时训练所有层级的模型,然后通过一个线性回归或优化模型,将各层预测值加权组合,得到既一致又最小化误差的最终预测。
数学上,设 \hat{y} 为各层级原始预测向量,S 为聚合矩阵(表示层级关系),目标是找到一组修正后的预测 \tilde{y},使得 S\tilde{y} = \tilde{y}_{upper}(一致性),且 \tilde{y} 与 \hat{y} 的差异最小化(最小二乘)。
三、代码实战:使用 scikit-learn 和 hierarchicalforecast 库
3.1 安装
pip install hierarchicalforecast statsmodels
3.2 数据结构
假设我们有 3 个单品(SKU_A, SKU_B, SKU_C)组成一个品类,总店就是全量。时间序列数据格式:
ds SKU_A SKU_B SKU_C
2024-01-01 10 15 5
2024-01-02 12 14 6
品类 = SKU_A + SKU_B + SKU_C,总店 = 品类(单店场景)。
3.3 生成基础预测(以 LightGBM 为例)
import pandas as pd
import numpy as np
from hierarchicalforecast.core import HierarchicalForecast
from hierarchicalforecast.methods import BottomUp, TopDown, OptimalCombination
# 假设已经得到每个 SKU 的预测(使用任何模型)
# Y_hat_df: 包含预测值的 dataframe,列 = ['ds', 'SKU_A', 'SKU_B', 'SKU_C', 'total']
Y_hat_df = ...
# 定义层级结构:S 矩阵
# 这里简化:SKU_A + SKU_B + SKU_C = category, category = total
S = np.array([
[1,0,0,1,1], # SKU_A -> category, total?
[0,1,0,1,1],
[0,0,1,1,1],
])
# 实际上 hierarchicalforecast 支持从文本定义,见文档
3.4 应用最优组合
# 使用 OptimalCombination 方法
reconciled = HierarchicalForecast(
models={'base': Y_hat_df},
reconciliation_methods=[OptimalCombination()]
).reconcile()
四、我的 API 中的实现
由于计算效率考虑,我的销量预测 API 目前采用 混合策略:
· 默认:自下而上(因为单品模型已经足够好,且用户通常关注单品)
· 可选:对需要品类预测的用户,提供 加权最优组合(基于历史误差协方差矩阵),耗时增加约 10%,但一致性提高 30% 以上。
API 请求示例:
POST /predict_hierarchy
{
"sku_list": ["MILK001", "YOGURT002"],
"aggregate_level": "category", # "sku", "category", "total"
"reconciliation": "optimal" # "bottom_up", "top_down", "optimal"
}
响应:
{
"sku_level": {...},
"category_level": {...},
"total_level": {...},
"reconciled": true,
"method": "optimal"
}
五、实战案例:乳制品类预测
某便利店有 5 个乳制品 SKU。以前分别预测,每周总预测误差波动很大。使用最优组合后:
指标 自下而上 最优组合
单品平均 WMAPE 14% 14%(无变化)
品类 WMAPE 18% 11%
单品与品类预测一致性 不一致(和差关系) 完全一致
品类预测误差降低 7 个百分点,且库存计划者不再纠结。
六、何时应该使用层次化预测?
· 需要向管理层汇报总店/品类预测:自下而上累积误差太大,需要修正。
· 存在资源分配约束:如总采购预算固定,需要在品类间优化分配。
· 多层级库存管理:中央仓库按品类备货,门店按 SKU 补货。
反之,如果你是单个店主,只关注几个 SKU,自下而上就足够了。
七、总结与展望
层次化预测解决了预测一致性问题,让不同粒度的决策能够对齐。我的 API 已经集成了最优组合方法,你可以免费试用。
下一篇文章预告:《在线学习:实时更新销量预测模型应对概念漂移》——当消费者行为随时间变化,如何让模型快速适应而不需重新训练。
互动问题:你遇到过“单品预测不准但品类预测挺准”的情况吗?你是如何做决策的?评论区分享。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)