机器学习在日化产品销量预测中的应用与实践
1. 项目概述:日化产品销量预测的机器学习实践
这个毕业设计项目选择了一个极具商业价值的课题——利用机器学习算法分析影响日化产品销量的关键因素,并构建预测模型。日化行业作为快消品领域的重要组成部分,其销售数据具有典型的时序性、季节性和多因素影响特征,非常适合作为机器学习算法的实践场景。
我在项目中采用了完整的数据科学工作流程:从数据采集与清洗开始,到特征工程构建,再到多种机器学习算法的比较与优化,最终部署可解释性分析工具SHAP来解读模型决策过程。整个项目不仅实现了高达87%的预测准确率,更重要的是发现了影响日化产品销量的三个关键因素:季节性指数、促销活动强度和竞品价格波动。
2. 数据准备与特征工程
2.1 数据来源与清洗
日化产品销售数据通常包含以下几个维度:
- 基础销售数据:日期、产品SKU、销售额、销售量
- 市场活动数据:促销类型、折扣力度、广告投放渠道
- 外部环境数据:节假日标记、天气情况、经济指标
- 竞品数据:主要竞争对手的价格变动、新品上市情况
数据清洗的关键步骤包括:
- 处理缺失值:对于促销活动等间歇性数据,采用向前填充法;对于连续型变量如天气数据,使用线性插值
- 异常值检测:使用IQR方法识别并处理异常销售记录
- 数据标准化:对价格、销量等不同量纲的数据进行Min-Max归一化
# 示例:数据清洗代码片段 def clean_data(df): # 处理缺失值 df['promotion_type'] = df['promotion_type'].fillna('no_promotion') df['discount_rate'] = df['discount_rate'].fillna(0) # 异常值处理 Q1 = df['sales_volume'].quantile(0.25) Q3 = df['sales_volume'].quantile(0.75) IQR = Q3 - Q1 df = df[~((df['sales_volume'] < (Q1 - 1.5*IQR)) | (df['sales_volume'] > (Q3 + 1.5*IQR)))] # 数据标准化 scaler = MinMaxScaler() df[['price','sales_volume']] = scaler.fit_transform(df[['price','sales_volume']]) return df2.2 特征构建技巧
基于领域知识,我构建了几类关键特征:
- 时序特征:将日期分解为年、月、周、日等周期特征,并添加节假日标记
- 滞后特征:创建过去7天、30天的销量移动平均值作为趋势指标
- 交叉特征:促销力度与价格的交互项,反映价格弹性
- 竞品相对特征:本品牌价格与竞品价格的比值
重要提示:构建滞后特征时需要注意数据泄漏问题,必须确保在训练集和测试集上采用不同的滚动窗口计算方式。
3. 模型构建与优化
3.1 算法选型对比
我测试了以下几种主流算法:
- 传统时序模型:ARIMA、Prophet
- 机器学习模型:随机森林、XGBoost、LightGBM
- 深度学习模型:LSTM、Transformer
通过交叉验证得到的性能对比:
| 模型类型 | MAE | RMSE | R² | 训练时间 |
|---|---|---|---|---|
| ARIMA | 0.142 | 0.186 | 0.632 | 5min |
| Prophet | 0.138 | 0.179 | 0.658 | 8min |
| 随机森林 | 0.121 | 0.162 | 0.721 | 15min |
| XGBoost | 0.112 | 0.154 | 0.748 | 20min |
| LSTM | 0.098 | 0.136 | 0.803 | 2h |
| Transformer | 0.095 | 0.132 | 0.815 | 3h |
3.2 深度学习模型优化
对于表现最好的Transformer模型,我进行了以下优化:
- 注意力机制改进:采用LogSparse注意力降低计算复杂度
- 特征嵌入:将离散特征(如产品类别、促销类型)转换为嵌入向量
- 损失函数设计:结合MAE和Quantile Loss,提高对极端值的预测能力
# Transformer模型核心代码 class SalesTransformer(nn.Module): def __init__(self, num_features, d_model=128, nhead=4, num_layers=3): super().__init__() self.embedding = nn.Linear(num_features, d_model) encoder_layer = nn.TransformerEncoderLayer(d_model, nhead) self.transformer = nn.TransformerEncoder(encoder_layer, num_layers) self.decoder = nn.Sequential( nn.Linear(d_model, 64), nn.ReLU(), nn.Linear(64, 1) ) def forward(self, x): x = self.embedding(x) x = self.transformer(x) x = self.decoder(x[:, -1, :]) # 只取最后时间步 return x4. 模型解释与业务洞察
4.1 SHAP可解释性分析
使用SHAP值分析发现:
- 促销活动的影响呈现非线性特征:折扣率在30%-50%区间效果最佳
- 价格敏感度:高端产品价格弹性低于低端产品
- 季节因素:夏季对防晒类产品影响最大,冬季对保湿类产品影响显著
import shap # 计算SHAP值 explainer = shap.Explainer(model) shap_values = explainer(X_test) # 可视化 shap.plots.beeswarm(shap_values)4.2 业务建议
基于模型分析,我向企业提出了三条关键建议:
- 促销策略优化:集中资源在关键季节(如春节前、618等)进行中度折扣促销
- 价格调整:对高端产品可适当提价,低端产品保持价格稳定
- 库存管理:根据预测提前调整区域仓库的库存分布
5. 系统实现与部署
5.1 技术架构设计
采用前后端分离架构:
- 前端:Vue.js + ECharts实现可视化
- 后端:Flask提供RESTful API
- 数据库:MySQL存储历史数据,Redis缓存预测结果
- 任务调度:Celery实现定时预测任务
5.2 关键接口设计
@app.route('/predict', methods=['POST']) def predict(): data = request.get_json() # 数据预处理 features = preprocess(data) # 模型预测 prediction = model.predict(features) # 生成解释 explanation = explainer(features) return jsonify({ 'prediction': prediction, 'explanation': explanation })6. 项目总结与经验分享
在完成这个项目的过程中,我总结了以下几点关键经验:
- 数据质量决定上限:花费60%的时间在数据清洗和特征工程上是值得的
- 模型复杂度与业务需求的平衡:并非越复杂的模型越好,XGBoost在大多数场景下已经足够优秀
- 可解释性的重要性:企业决策者更关心"为什么"而不仅仅是预测结果
- 工程化考量:将模型从Jupyter Notebook迁移到生产环境需要充分考虑性能和维护成本
对于想尝试类似项目的同学,我建议:
- 先从简单的线性模型开始建立baseline
- 使用MLflow或Weights & Biases跟踪实验过程
- 尽早与业务方沟通,确保模型输出符合实际决策需求
这个项目完整的源代码和论文已经开源在GitHub上,包含详细的文档说明和示例数据集,可以帮助初学者快速复现整个分析流程。通过这个实践,我深刻体会到数据科学在传统零售行业的巨大应用潜力。