间歇性需求预测与 TimeGPT
间歇性需求(intermittent demand)是商业预测中很常见、也很棘手的一类问题。某些商品大多数日期销量为 0,偶尔出现订单;某些备件、慢销品和长尾 SKU(Stock Keeping Unit, SKU)也有类似特征。普通模型容易被大量零值误导,或者给出负需求。本章以 TimeGPT 和经典间歇性需求模型为例,说明间歇性需求预测(Intermittent Demand Forecasting)如何处理这类数据、如何评估结果,以及外生变量为什么重要。
学习目标¶
完成本章后,你应该能够:
识别间歇性需求和普通平稳需求(stationary demand)的区别。
区分“需求是否发生”和“发生后需求有多大”两个问题。
使用
log1p变换(log-one-plus transform)降低尺度差异并避免负值预测。用 TimeGPT 对多条需求序列进行预测。
理解本地 Chronos-2 模型如何做零样本预测。
将多条长短不一的时间序列整理成长表格式。
将 TimeGPT 与 Croston、IMAPA、TSB 等经典基线比较。
判断外生变量是否能改善间歇性需求预测。
什么是间歇性需求¶
间歇性需求的典型特征是“很多 0,少数非 0”。例如备件、冷门商品、长尾电商 SKU、特殊医疗物资和低频企业采购。它和普通日销商品不同:没有需求的日子很多,但一旦出现需求,数量可能并不小。
还可以看一些更极端的例子:航空发动机、昂贵设备、关键零部件、光刻机相关工具等。这类产品可能很长时间只有 0 或 1 次需求,但一次需求就关系到高成本、高服务水平或关键生产能力。对这类序列,预测平均销量不是唯一目标,判断需求是否会发生同样重要。
这种数据会给模型带来三个困难。
第一,均值很低但方差可能很高。简单平均会低估峰值。
第二,百分比误差不稳定。真实值为 0 时,MAPE 无法定义。
第三,业务成本常常不对称。备件缺货可能造成停机损失,库存过多又会占用资金。
因此,间歇性需求可以拆成两个问题:第一,未来某天或某周是否会发生需求;第二,如果发生需求,需求量有多大。Croston 类方法正是沿着这个思路,把需求大小和需求间隔分开处理 Croston, 1972。时间序列基座模型也应该在评估中接受这个拆分,而不是只看一条平滑曲线是否贴近平均值。
数据准备¶
示例 notebook 使用 M5 子集数据,包含 unique_id、ds、y 以及价格、事件类型等外生变量。基本格式和前面章节一致:
df["ds"] = pd.to_datetime(df["ds"])
df = df.sort_values(["unique_id", "ds"]).reset_index(drop=True)建模前先可视化单条序列。间歇性需求的图形通常会出现长时间贴近 0、偶尔跳起的尖峰。这个检查能帮助我们判断是否需要特殊模型,而不是盲目套用常规预测流程。
M5 这类多序列数据还提醒我们:间歇性需求不是一个单序列问题。不同商品、门店和品类之间可能共享节假日、价格、促销和地区消费习惯。TimeGPT 这类时间序列基座模型的优势之一,是能够在多条序列中学习共同结构;但前提是 unique_id、时间列、目标列和外生变量都整理正确。
Chronos-2 练习使用了类似的数据组织思想。时间序列数据和普通表格数据的一个重要差别,是不同序列长度可能不一致。如果用宽表把 H1、H2、H3 等序列横向摆放,缺失和切分都会很麻烦;长表则把所有序列纵向拼接,每一行是一个观测点,用 ID 区分它属于哪条序列。
长表至少需要三列:
| 列 | 含义 |
|---|---|
item_id 或 unique_id | 时间序列编号,例如 H1, H2, H414 |
timestamp 或 ds | 时间顺序,可以是真实日期,也可以是顺序编号 |
target 或 y | 要预测的目标数值,通常称为目标列(target column) |
M4 小时级示例数据有 414 条序列,拼接后约几十万个观测点。长表格式可以自然容纳长短不一的序列,也方便批量预测、分布式存储和后续评估。无论使用 TimeGPT API、Chronos-2 本地模型,还是经典统计基线,先把这三列整理正确,都是多序列预测的共同入口。
变换与切分¶
notebook 使用 log1p 变换:
df_t = df.copy()
df_t["y"] = np.log(df_t["y"] + 1)log1p 有两个作用。第一,它压缩大需求值,降低尖峰对模型的影响。第二,它能处理 0,因为 。预测后再用 还原到原尺度。
评估时按每个 unique_id 留出最后 28 天:
H = 28
test_df = df_t.groupby("unique_id", group_keys=False).tail(H)
train_df = df_t.drop(test_df.index).reset_index(drop=True)多序列任务必须按序列分组切分,不能简单取整个表最后 28 行。
使用 TimeGPT¶
TimeGPT 可以直接接收包含 unique_id、ds 和 y 的多序列表。示例中使用长预测模型、80% 区间和少量微调步数:
fcst_df = client.forecast(
df=train_df,
h=H,
level=[80],
finetune_steps=10,
finetune_loss="mae",
model="timegpt-1-long-horizon",
time_col="ds",
target_col="y",
id_col="unique_id",
)正式 notebook 不应写真实 API key。使用环境变量:
from nixtla import NixtlaClient
client = NixtlaClient(api_key=os.environ["NIXTLA_API_KEY"])预测后要把所有预测列从 log 空间还原到原尺度,再与测试集真实值合并计算误差。
使用 TimeGPT 时还要记住,它不是免评估的答案。时间序列基座模型能利用跨序列预训练经验,适合冷启动、长尾和多序列场景 Garza et al., 2024;但在一个具体库存问题中,它仍然必须和 Croston、IMAPA、TSB、LightGBM、DeepAR、NHITS 等基线放在同一测试集上比较。
本地 Chronos-2 练习¶
本地时间序列基座模型预测不必依赖远程 API。流程是先下载并解压预训练模型文件,然后在 notebook 中指定模型目录,加载 pipeline,再把长表格式的历史数据传入模型。Chronos-2 延续了把时间序列 token 化并进行零样本预测的路线 Ansari et al., 2025。模型目录中通常包含 config.json 和 model.safetensors;示例模型权重约为数百 MB,因此不少笔记本电脑可以用 CPU 跑通,只是速度慢于 GPU。
调用这类 pipeline 时,核心参数和 API 预测很相似:
context_df:包含历史观测的长表。id_column:序列 ID 列。timestamp_column:时间列。target_column:目标变量列。prediction_length:向未来预测多少期。quantile_levels:需要输出的分位数水平。
示例对 414 条 M4 小时级序列同时预测未来 24 期。因为模型推理阶段不是重新训练,而是使用已经训练好的权重,所以几百条序列的预测可以在几十秒到一分钟量级完成。这个速度说明,时间序列基座模型可以成为实时或准实时预测系统的一部分,但前提是模型文件、依赖版本和硬件资源都稳定。
Chronos-2 也能输出预测区间。设置 quantile_levels = [0.1, 0.9] 时,输出的是 10% 和 90% 分位数,中间是 80% 区间。画图时应同时展示历史值、真实未来值、点预测和上下分位数,这样才能看到模型是否只是给出一条平滑曲线,还是对不确定性有合理表达。
经典基线¶
间歇性需求有专门的统计模型。示例 notebook 使用 StatsForecast 比较:
CrostonClassic:分别估计需求大小和需求间隔。
CrostonOptimized:优化平滑参数的 Croston 版本。
IMAPA(Intermittent Multiple Aggregation Prediction Algorithm):在多种聚合尺度上处理间歇性需求。
TSB(Teunter-Syntetos-Babai):用需求发生概率和需求大小共同建模。
这些基线很重要。TimeGPT 是强模型,但不能只和空模型比较。针对间歇性需求的特征化和模型选择研究也说明,长尾和零值序列需要专门诊断,而不能只套普通销量预测流程 Li et al., 2023。只有当它在相同训练集、测试集和指标下超过合理基线,才说明引入时间序列基座模型有实际价值。
评估指标¶
notebook 使用 MAE 汇总 TimeGPT 和基线模型。对于间歇性需求,MAE 比 MAPE 更稳健,因为真实值为 0 的样本很多。评估时应按序列计算,再汇总到整体平均,避免销量大的序列完全主导结果。
除了 MAE,业务中还可以关注:
缺货次数或缺货概率。
库存持有成本。
服务水平。
高需求日的召回能力。
预测区间覆盖率(prediction interval coverage)。
如果模型平均误差低,但总是错过少数关键需求尖峰,业务上仍可能不可接受。
这类任务尤其要避免让“最差的一次预测”伤害关键决策。少数尖峰日可能比平均误差更重要,因此评估时除了 MAE,还应检查高需求日、缺货风险和预测区间覆盖。
还可以把评估拆成两张表。第一张表评价所有日期的整体误差,回答模型日常表现如何。第二张表只看非 0 日期或高需求日期,回答模型是否抓住了真正需要备货的时刻。对于关键备件,第二张表往往比第一张表更接近业务损失。
外生变量¶
间歇性需求往往受事件影响,例如促销、节假日、价格变化和特殊活动。notebook 中把事件类型列作为未来已知外生变量传入 TimeGPT:
event_cols = [
"event_type_Cultural",
"event_type_National",
"event_type_Religious",
"event_type_Sporting",
]外生变量的关键要求是:预测未来时这些变量必须已知或可可靠预测。这类输入通常称为未来已知外生变量(future known exogenous variables)。节假日通常已知,未来价格和促销计划也可能已知;但未来新闻热度或突发事件不能随便当作已知输入。
外生变量要区分“历史可见”和“未来可用”。历史价格、过去促销和过去事件可以帮助模型学习关系,但预测未来时,只有已经排定的节假日、促销计划、价格策略或已知活动才能作为未来输入。把未来才会知道的信息放入模型,会造成数据泄漏,让评估结果虚高。
销售需求练习更直观地展示了协变量的作用。第一次预测只给模型 ID、时间和历史销量,模型能够捕捉部分下降趋势,但越往后越容易滞后或错位。第二次加入 Open、Promo、SchoolHoliday、StateHoliday、Customers 等变量后,预测曲线更贴近真实值,区间也明显收窄。这说明很多销量变化不是由历史销量本身决定的,而是由门店是否营业、促销、假期和客流共同驱动。
这些协变量可以理解为进入特征矩阵 X 的额外列。经过投影后,它们会影响注意力权重和最终预测。不过,模型究竟利用了变量名的语义,还是利用了列值与目标之间的统计关系,需要实验验证。一个可做的练习是打乱协变量列名或改变列顺序,观察预测是否变化;如果变化很大,就要进一步检查模型对字段名、字段含义和数据结构的依赖。
不同频率下的模型选择¶
我们提醒你,TimeGPT 在月度和周度等较低频数据上表现通常更稳健,而在高频数据上,树模型如 LightGBM、XGBoost 在量化和高频交易中仍非常重要。这提醒我们,时间序列基座模型不是所有频率的唯一答案。
低频经济和商业预测重视跨序列泛化和稳健性;高频金融或交易数据更强调微结构特征、低延迟和局部模式。模型选择必须服从数据频率和业务决策周期。
TimeGPT 应放在一组基线模型中比较,包括 LightGBM、LSTM、DeepAR、DFT 和 NHITS。重点不是宣布某个模型永远最好,而是说明模型表现会随数据频率、预测步长和业务场景改变。月度和周度商业数据中,TimeGPT 这类预训练模型常能利用跨序列信息取得较稳健表现;但在高频交易或非常局部的短期预测中,LightGBM、XGBoost 等树模型仍可能更有优势。
对间歇性需求来说,频率选择本身就是建模选择。日度数据可能太稀疏,周度或月度聚合后规律更清楚,但会牺牲补货时点的精度。实践中可以同时比较日度、周度和月度版本:低频版本用于战略备货,高频版本用于短期补货提醒。
从预测到库存决策¶
间歇性需求预测最终要服务库存和服务水平。一个预测值可以转化为订货量、安全库存、补货触发点或人工复核清单。模型输出越接近自动化决策,越需要把业务成本写进评估。
例如,某个模型把大多数 0 预测得很准,但错过一次关键备件需求,可能导致设备停机;另一个模型平均误差略高,但能提前识别关键需求日,业务上反而更有价值。因此,本章的评估不应停在 MAE 排名,而应继续问:这个模型能不能降低缺货,能不能控制库存,能不能让人工复核集中在最有风险的 SKU 上?
小结¶
间歇性需求预测的关键不是把 0 当作普通小数值,而是理解需求发生和需求大小的双重不确定性。TimeGPT 提供了强大的通用预测能力,但仍需要 log 变换、合理基线、稳健指标、外生变量检查和业务成本解释。不要让平均误差掩盖关键尖峰,也不要让最坏的一次预测伤害关键决策,是这类问题的底线。
练习¶
找一条长尾商品需求序列,统计 0 值占比和非 0 需求的分布。
比较原始尺度和
log1p尺度下的预测图。用 Croston、IMAPA 和 TimeGPT 计算同一测试集的 MAE。
单独统计非 0 日期或高需求日期的误差,并和整体 MAE 比较。
设计一个比 MAE 更贴近库存决策的评价指标。
判断一个外生变量是否能在预测未来时提前知道,并说明原因。
比较日度、周度和月度聚合下同一商品的预测难度。
将一组长短不一的时间序列整理成长表,并说明
id_column、timestamp_column和target_column分别对应什么。比较只用历史销量和加入
Promo、Holiday、Customers等协变量后的预测图与区间宽度。
参考文献¶
- Croston, J. D. (1972). Forecasting and Stock Control for Intermittent Demands. Journal of the Operational Research Society, 23(3), 289–303. 10.1057/jors.1972.50
- Garza, A., Challu, C., & Mergenthaler-Canseco, M. (2024). TimeGPT-1. 10.48550/arXiv.2310.03589
- Ansari, A. F., Shchur, O., Küken, J., Auer, A., Han, B., Mercado, P., Rangapuram, S. S., Shen, H., Stella, L., Zhang, X., Goswami, M., Kapoor, S., Maddix, D. C., Guerron, P., Hu, T., Yin, J., Erickson, N., Desai, P. M., Wang, H., … Bohlke-Schneider, M. (2025). Chronos-2: From Univariate to Universal Forecasting. 10.48550/arXiv.2510.15821
- Li, L., Kang, Y., Petropoulos, F., & Li, F. (2023). Feature-Based Intermittent Demand Forecast Combinations: Accuracy and Inventory Implications. International Journal of Production Research, 61(22), 7557–7572. 10.1080/00207543.2022.2153941