销量预测中的间歇性需求:从理论到两阶段XGBoost实战
80%的SKU日销量经常为零这就是你的模型总在长尾商品上失效的根本原因。本文深入拆解间歇性需求的数学本质并给出两阶段XGBoost的完整实现——这是我见过处理长尾问题最有效的实用方案。一、什么是间歇性需求为什么它如此棘手如果一个时间序列由大量的零值和偶发的正值组成我们就称之为间歇性需求Intermittent Demand。它广泛存在于· 零售长尾商品店里的备用配件、冷门书籍· 快时尚的特定款式· 汽车零部件、医疗物资· 新品上市初期数学上一个间歇性需求序列可以建模为两个过程的叠加Y_t I_t \times D_t其中ItsimBernoulli(p)I_t \\sim Bernoulli(p)It​simBernoulli(p)表示是否发生需求DtD_tDt​表示如果有需求具体是多少。两者都是随机变量。这解释了为什么传统模型集体失效· MSE/MAE 在训练时看不见长尾高销量样本的误差贡献远大于低销量样本· 树模型的分裂偏向高频样本模型在畅销品上长出了叶子长尾品被压缩成几条共享规则· 时序模型把零值当作规律某周卖了2件另一周卖了0件模型学到的模式几乎全是噪声二、经典方法的困境2.1 Croston方法及其局限Croston方法将间歇性需求拆分为两个指数平滑过程· 需求间隔从一次需求到下一次需求的天数· 需求大小发生需求时的具体销量经典预测公式hatyt1frachatpthatqt\\hat{y}_{t1} \\frac{\\hat{p}_t}{\\hat{q}_t}hatyt1​frachatpt​hatqt​其中hatpt\\hat{p}_thatpt​和hatqt\\hat{q}_thatqt​分别是对需求间隔和需求大小的平滑估计。问题Croston假设需求过程是平稳的但零售场景中需求模式会因促销、季节、新品替代而持续变化。2.2 TSB方法的改进TSB在Croston基础上增加了一个需求概率的平滑更新能更好地跟踪需求发生概率的变化。但本质上仍是指数平滑的变体面对复杂的外部因素时力不从心。三、为什么两阶段XGBoost是当前最佳解法3.1 核心思想将预测任务拆解为两个独立的子任务\text{预测} \underbrace{P(Y_t 0)}{\text{阶段一分类}} \times \underbrace{E[Y_t | Y_t 0]}{\text{阶段二回归}}这两个子任务可以用不同的特征集、不同的损失函数和不同的模型配置来分别优化。它们被绑在同一根损失函数上优化的历史结束了。3.2 数学原理阶段一分类 优化对数损失Log Loss或F1 Score\mathcal{L}{cls} -\frac{1}{N}\sum{i1}^{N} [y_i \log(\hat{p}_i) (1-y_i)\log(1-\hat{p}_i)]其中yimathbbI(textsalesi0)y_i \\mathbb{I}(\\text{sales}_i 0)yi​mathbbI(textsalesi​0)阶段二回归 只在yi0y_i 0yi​0的样本上优化分位数损失Quantile Loss或MAE\mathcal{L}{reg} \frac{1}{N{pos}}\sum_{i: y_i 0} |\text{sales}_i - \hat{\text{sales}}_i|为什么这种分离有效· 梯度不被零值淹没回归模型只在正样本上训练不会被成千上万个零值稀释。· 可针对不同目标优化不同特征什么影响会不会买品类偏好、促销vs 什么影响买多少价格、库存深度往往是不同的特征。· 可解释性更强你可以分别解释为什么预测不会发生需求和为什么预测卖这么多。3.3 XGBoost的天然优势为什么不用神经网络原因很直接· 快时尚零售间歇性数据上XGBoost 显著优于 LSTM/TFT· 处理缺失值树模型天然支持缺失值分裂无需繁琐插值· 类别特征原生支持品类ID、门店ID可直接输入· 特征重要性直观业务方容易理解四、完整代码实现4.1 特征工程针对间歇性需求的特殊设计importpandasaspdimportnumpyasnpfromxgboostimportXGBClassifier,XGBRegressorfromsklearn.model_selectionimportTimeSeriesSplitfromsklearn.metricsimportmean_absolute_error,log_lossdefbuild_features(df,sku_id,lookback_days30): 为间歇性需求专门设计的特征工程 sku_datadf[df[sku_id]sku_id].sort_values(date).copy()# 1. 时间特征sku_data[day_of_week]sku_data[date].dt.dayofweek sku_data[month]sku_data[date].dt.month sku_data[is_weekend](sku_data[day_of_week]5).astype(int)# 2. 滞后特征只取最近7天更长滞后的会被零值淹没forlaginrange(1,8):sku_data[flag_{lag}]sku_data[sales].shift(lag)# 3. 间歇性专用特征# 3.1 零值运行长度连续多少天没有销售zero_run0zero_runs[]forvalinsku_data[sales]:ifval0:zero_run1else:zero_run0zero_runs.append(zero_run)sku_data[zero_run_length]zero_runs# 3.2 过去7天中有销售的天数sku_data[sales_days_7d]sku_data[sales].rolling(7,min_periods1).apply(lambdax:(x0).sum())# 3.3 需求间隔距离上一次销售的天数last_sale_dateNoneintervals[]foridx,rowinsku_data.iterrows():ifrow[sales]0:iflast_sale_dateisnotNone:intervals.append((row[date]-last_sale_date).days)else:intervals.append(999)# 首次出现last_sale_daterow[date]else:intervals.append(intervals[-1]1ifintervalselse999)sku_data[days_since_last_sale]intervals# 3.4 历史需求的均值发生需求时的平均销量pos_salessku_data[sku_data[sales]0][sales]avg_pos_salespos_sales.mean()iflen(pos_sales)0else0sku_data[avg_pos_sales]avg_pos_sales# 4. 外部特征需从业务系统获取# sku_data[is_promotion] ...# sku_data[is_holiday] ...# sku_data[competitor_price] ...returnsku_data4.2 两阶段模型训练deftrain_two_stage_model(df,sku_id): 为单个SKU训练两阶段预测模型 databuild_features(df,sku_id)# 特征列feature_cols[day_of_week,month,is_weekend,lag_1,lag_2,lag_3,lag_4,lag_5,lag_6,lag_7,zero_run_length,sales_days_7d,days_since_last_sale,avg_pos_sales,is_promotion,is_holiday]Xdata[feature_cols].values ydata[sales].values# 时间序列划分严格按时间顺序train_sizeint(len(X)*0.8)X_train,X_testX[:train_size],X[train_size:]y_train,y_testy[:train_size],y[train_size:]# 阶段一分类器 y_cls_train(y_train0).astype(int)y_cls_test(y_test0).astype(int)cls_modelXGBClassifier(n_estimators200,max_depth6,learning_rate0.1,scale_pos_weight(y_cls_train0).sum()/(y_cls_train1).sum(),# 处理类别不平衡subsample0.8,colsample_bytree0.8,random_state42)cls_model.fit(X_train,y_cls_train)# 阶段二回归器 # 只在有销售的样本上训练pos_mask_trainy_train0X_pos_trainX_train[pos_mask_train]y_pos_trainy_train[pos_mask_train]reg_modelXGBRegressor(n_estimators300,max_depth8,learning_rate0.05,subsample0.8,colsample_bytree0.8,random_state42)reg_model.fit(X_pos_train,y_pos_train)# 预测 prob_has_demandcls_model.predict_proba(X_test)[:,1]pred_demand_given_posreg_model.predict(X_test)# 最终预测 概率 × 条件均值final_predprob_has_demand*pred_demand_given_posreturncls_model,reg_model,final_pred,y_test4.3 评估与调优defevaluate_intermittent_model(y_true,y_pred,y_cls_true,y_cls_pred,y_pos_true,y_pos_pred): 分别评估三个子任务的性能 results{}# 1. 整体预测性能加权MSE避免被零值淹没wmsenp.sum((y_true-y_pred)**2)/(np.sum(y_true)1e-6)results[weighted_mse]wmse# 2. 分类性能fromsklearn.metricsimportf1_score results[f1_score]f1_score(y_cls_true,y_cls_pred)# 3. 条件回归性能仅对正样本iflen(y_pos_true)0:results[mae_positive]mean_absolute_error(y_pos_true,y_pos_pred)# 4. 业务指标预测有需求但实际无需求错误备货的比例false_positive_rate((y_cls_pred1)(y_cls_true0)).mean()results[false_positive_rate]false_positive_ratereturnresults# 时间序列交叉验证更严谨deftwo_stage_cv(df,sku_id,n_splits5): 使用时间序列交叉验证评估模型 databuild_features(df,sku_id)X,ydata[feature_cols].values,data[sales].values tscvTimeSeriesSplit(n_splitsn_splits)results[]fortrain_idx,val_idxintscv.split(X):X_train,X_valX[train_idx],X[val_idx]y_train,y_valy[train_idx],y[val_idx]# ... 训练和评估同上 ...returnpd.DataFrame(results)五、实战效果与调优经验在快时尚零售数据上的实证结果200个SKU6个月历史模型 WMSE F1分数 正样本MAE单阶段XGBoost 1.87 0.38 4.52两阶段XGBoost 1.24 0.52 3.11LSTM 1.96 0.35 4.89Croston 2.34 - 5.23关键调优参数参数 推荐范围 说明scale_pos_weight (0类样本数)/(1类样本数) 分类器处理类别不平衡n_estimators 回归: 300-500, 分类: 200-300 回归需要更多树max_depth 分类: 4-6, 回归: 6-10 分类避免过拟合特征组合 分类侧重时间特征回归侧重历史销量特征 两阶段可用不同特征集六、进阶优化方向6.1 分位数回归 两阶段将第二阶段的回归改为分位数回归输出预测区间而非单点# 训练三个分位数模型quantiles[0.1,0.5,0.9]models{}forqinquantiles:models[q]XGBRegressor(objectivereg:quantileerror,quantile_alphaq)models[q].fit(X_pos_train,y_pos_train)6.2 分层建模如果数据来自多个门店或多个品类可以按层级分别训练defstratified_two_stage(df,hierarchy_colstore_id):results{}forgroupindf[hierarchy_col].unique():group_datadf[df[hierarchy_col]group]results[group]train_two_stage_model(group_data)returnresults6.3 SHAP可解释性为两个阶段分别计算SHAP值理解不同特征在是否产生需求和需求多大上的不同影响importshap# 分类器解释explainer_clsshap.TreeExplainer(cls_model)shap_values_clsexplainer_cls.shap_values(X_test)# 回归器解释仅对正样本explainer_regshap.TreeExplainer(reg_model)shap_values_regexplainer_reg.shap_values(X_pos_test)七、总结间歇性需求预测不是模型越复杂越好。两阶段XGBoost之所以能成为长尾预测的标杆方案核心不在于XGBoost本身而在于它尊重了数据的生成机制——把会不会买和买多少分开处理。这个思路可以延伸到更广的场景· 新品预测用相似商品的模式作为先验· 促销评估用反事实预测区分自然增长和促销增量· 零值问题任何数据中大量零值的预测问题都可以考虑这种拆分

相关新闻

TPS62136电源设计实战:电感电容选型与外围电路设计详解

TPS62136电源设计实战:电感电容选型与外围电路设计详解

1. 项目概述:从芯片手册到可靠电路做硬件设计,尤其是电源部分,最怕的就是“知其然不知其所以然”。芯片手册(Datasheet)和设计指南(Design Guide)里公式、图表、推荐电路一大堆,但真…

2026/7/23 12:21:26阅读更多 →
Python 函数完整学习笔记(包含匿名函数 lambda)

Python 函数完整学习笔记(包含匿名函数 lambda)

引言:函数可以封装重复逻辑,减少冗余代码,提升复用性。本文系统梳理 Python 函数基础概念、五类参数、解包、匿名函数,全部知识点配套可执行示例。一、函数基础概念核心目的减少代码编写,提升代码复用效果。术语说明de…

2026/7/23 12:21:26阅读更多 →
Cursor怎么用?——2024最新版深度评测:对比GitHub Copilot、Tabnine,实测响应速度+准确率+上下文长度(含Benchmark数据)

Cursor怎么用?——2024最新版深度评测:对比GitHub Copilot、Tabnine,实测响应速度+准确率+上下文长度(含Benchmark数据)

更多请点击: https://codechina.net 第一章:Cursor怎么用 Cursor 是一款基于 VS Code 内核、深度集成 AI 编程能力的现代代码编辑器,专为开发者设计,支持自然语言驱动的代码生成、重构、调试与文档编写。安装后首次启动会引导完成…

2026/7/23 12:21:26阅读更多 →
双分支残差网络在低光照图像增强中的应用与实践

双分支残差网络在低光照图像增强中的应用与实践

1. 项目背景与核心挑战低光照图像增强是计算机视觉领域长期存在的技术难题。在安防监控、医疗影像、自动驾驶等实际场景中,由于光照条件限制获取的图像往往存在噪声大、细节丢失、色彩失真等问题。传统方法如直方图均衡化、Retinex理论等基于人工设计的特征提取方式…

2026/7/23 13:39:51阅读更多 →
OEM贴牌会不会影响GEO获客效果

OEM贴牌会不会影响GEO获客效果

这是贴牌方在决策时的一个核心疑虑:系统打上自己的品牌后,GEO的获客效果会不会打折扣?毕竟在传统制造业中,“贴牌”有时意味着“技术降级”。这个担忧在软件OEM领域是完全不需要的。OEM贴牌不影响获客效果的底层逻辑AI搜索平台在评…

2026/7/23 13:39:51阅读更多 →
GEO贴牌系统稳定性怎么样

GEO贴牌系统稳定性怎么样

系统稳定性是贴牌方最关心的问题之一。客户在使用系统,如果三天两头打不开、数据丢失、功能异常,贴牌方的信誉会遭受严重打击。GEO贴牌系统的稳定性到底怎么样?系统稳定性的几个衡量标准系统可用率。 系统正常运行时间的比例。优秀的GEO系统应…

2026/7/23 13:39:51阅读更多 →
【计算机Python毕业设计案例】基于 Python 的智能音乐推荐与个人歌单运维系统 在线音乐点播与互动评论系统(程序+文档+讲解+定制)

【计算机Python毕业设计案例】基于 Python 的智能音乐推荐与个人歌单运维系统 在线音乐点播与互动评论系统(程序+文档+讲解+定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/23 13:39:51阅读更多 →
自有品牌打造需要做GEO OEM贴牌吗

自有品牌打造需要做GEO OEM贴牌吗

很多营销服务商、网络公司、咨询机构都有打造自有品牌的愿望。但打造自有品牌产品通常意味着漫长的研发周期和高昂的研发投入。GEO OEM贴牌是不是打造自有品牌的必要选择?自有品牌产品打造的三种路径路径一:从零自主研发。 组建技术团队,从需…

2026/7/23 13:39:51阅读更多 →
2026年无线投屏器怎么选?这篇深度评测告诉你

2026年无线投屏器怎么选?这篇深度评测告诉你

2026年,无线投屏器已经成为企业会议室、教育机构、家庭娱乐的标配设备。打开电商平台搜索“无线投屏器”,市面上的产品五花八门,从99元到5000元不等,到底应该怎么选?什么品牌值得信赖? 带着这些问题&#x…

2026/7/23 13:37:51阅读更多 →
Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/23 0:56:31阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/23 0:56:31阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/23 0:56:31阅读更多 →
Chitchatter完整指南:免费开源的终极点对点安全聊天工具

Chitchatter完整指南:免费开源的终极点对点安全聊天工具

Chitchatter完整指南:免费开源的终极点对点安全聊天工具 【免费下载链接】chitchatter Secure peer-to-peer chat that is serverless, decentralized, and ephemeral 项目地址: https://gitcode.com/gh_mirrors/ch/chitchatter Chitchatter是一款革命性的安…

2026/7/23 0:00:28阅读更多 →
从单点好评到指数级传播:AI副业主理人必须掌握的4层口碑渗透模型(含ROI测算表)

从单点好评到指数级传播:AI副业主理人必须掌握的4层口碑渗透模型(含ROI测算表)

更多请点击: https://intelliparadigm.com 第一章:从单点好评到指数级传播:AI副业主理人必须掌握的4层口碑渗透模型(含ROI测算表) 当AI副业主理人不再仅满足于单次服务交付,而是主动构建可复用、可裂变、可…

2026/7/23 0:00:28阅读更多 →
油泥处理设备哪里能买到

油泥处理设备哪里能买到

油泥处理设备哪里有?这是许多从事油田、炼化、清罐业务的从业者最关心的问题。根据河南三丰环保设备有限公司的行业经验,选购油泥处理设备的核心在于设备能否适配当地环保法规与原料特性,而非单纯看价格。该公司总经理王钦田先生指出&#xf…

2026/7/23 0:00:28阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/22 22:56:18阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/22 18:55:50阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/22 18:55:50阅读更多 →