机器学习预测客户购买特定产品:目标变量季节性不平衡的优化方案咨询
针对季节性极强的类别不平衡问题的解决方案
这是个很典型的时间序列+类别不平衡混合问题——季节性带来的不是普通的正负样本不均,而是和时间强绑定的分布偏移:旺季(12月)的正样本密度和淡季完全不是一个量级,直接用普通方法肯定会让模型“躺赢”在旺季,淡季彻底失效。分享几个我实际项目里用过的有效方案:
一、先从数据层面“对齐”分布,别急着改目标变量
- 时间感知的分层采样与交叉验证
普通的随机采样/拆分,要么会让训练集塞满12月的样本,模型学不到淡季的模式;要么验证集里没几个淡季正样本,根本测不出真实性能。一定要做按月份分层的时间序列交叉验证:比如用TimeSeriesSplit的时候,每个fold里都保留所有月份的样本,尤其是要保证非12月的正样本(购买用户)在训练和验证集中都有足够的占比。比如你有5年数据,可以按年拆分,每个训练集包含前4年的所有月份,验证集用第5年的每个月份单独测试,这样能清晰看到模型在每个月的表现。 - 把季节性特征“喂透”给模型
别让模型自己猜“什么时候是旺季”,直接把时间维度的特征做细:- 月份的one-hot编码或者目标编码(目标编码可以结合该月份的历史购买率);
- 距离12月的天数/周数(比如11月1日距离12月1日是30天,这个特征能捕捉到旺季前的预热期);
- 用户的历史购买时间特征(比如该用户过去2年的12月是否购买过,或者最近一次购买的月份);
- 当年的促销日历特征(比如是否在黑五、圣诞促销期内)。
二、针对不平衡的处理,要结合时间特性
- 加权损失函数(最推荐)
普通的交叉熵损失会让模型偏向于预测“不购买”(因为淡季负样本太多),或者只在12月预测“购买”。给不同月份的正样本设置不同的权重:比如计算每个月份的正样本占比,权重设为1/该月正样本占比,这样非12月的正样本权重会远高于12月,强迫模型去学习淡季的购买模式。举个例子,如果12月正样本占比是10%,非12月是0.5%,那非12月正样本的权重就是200,12月是10,这样模型会更重视淡季的少数正样本。 - 时间安全的过采样/欠采样
不要用普通的SMOTE(会破坏时间序列的顺序,引入数据泄露),而是:- 过采样:只在同一个月份内对正样本进行过采样(比如复制非12月的正样本,或者用SMOTE在同月份的特征空间内生成合成样本);
- 欠采样:适当减少12月的负样本(没购买的用户),但要保留足够的负样本以学习旺季的“不购买”模式,比如把12月的负样本按1:5的比例和正样本混合。
三、目标变量要不要调整?看业务需求
- 不建议直接修改原始目标变量:如果你的核心需求是“预测任意月份客户是否会购买该产品”,修改目标变量(比如改成“年度是否购买”)会偏离业务目标。
- 分场景建模(更实用):训练两个独立模型:一个专门处理12月的数据,一个处理非12月的数据。这样每个模型都是在同分布的数据上训练,避免了跨季节的分布偏移问题。之后可以做一个简单的路由逻辑:根据当前月份调用对应的模型。
- 可选:调整目标定义(如果业务允许):比如把目标改成“客户在接下来3个月内是否会购买该产品”,这样能平滑季节性的影响——比如11月的样本会包含12月的购买行为,淡季的样本也能覆盖到旺季的购买,适合做长期客户分层的场景。
四、评估时一定要按月份拆分,别只看整体指标
- 不要只看整体的准确率、F1-score,要按每个月份单独计算精确率、召回率、F1,确保淡季的性能达标。比如如果整体F1是0.8,但非12月的召回率只有0.1,那模型根本没解决你的问题。
- 用时间序列验证集:比如用2018-2021年的数据训练,2022年每个月的数据做验证,看模型在2022年1-11月和12月的表现是否一致,这样的评估结果才是真实可靠的。
内容的提问来源于stack exchange,提问作者J.K.




