使用 Python 预测沃尔玛销售额(机器学习模型)

2025年1月5日 | 阅读8分钟

沃尔玛是国内购物最受欢迎的零售企业之一,也是最大的商家之一。其所有产品类别的无与伦比的折扣和价格降低是其特色,因此,去其实体店购物本身就是一次冒险。这是一家年销售额达 5670 亿美元的零售企业。沃尔玛设有数据科学与分析部门,该部门运用各种数据科学技术来改善客户、顾客和员工关系。这些技术包括产品/客户细分、销售预测以及基于客户购买习惯的产品推荐。

问题陈述(业务需求)

2014 年,沃尔玛在 Kaggle 上举办了一场招聘竞赛。参赛者收到了 45 个沃尔玛门店在不同地区的历史销售数据。我们负责预测每个门店(有多个部门)的部门级销售额。此外,沃尔玛还会举办一系列年度促销折扣活动。最大的四次降价发生在主要节假日前:超级碗、劳动节、感恩节和圣诞节。与非节日周相比,包含这些节日的周的评估权重提高了五倍。在此次竞赛中,面临的挑战之一是在缺乏完美或全面的历史数据的情况下,模拟这些节日期间降价的影响。

理解业务需求和数据

我的目标是利用基于历史数据训练的机器学习模型来估算未来的销售数据,这是一个商业挑战。通过销售预测,每家公司都能做出更好的决策。它支持风险管理、预算编制和总体公司规划。它使企业能够有效地管理其现金流并在未来为扩张分配资源。通过精确估算支出和收入,企业可以预测其短期和长期成功。

数据库.CSV 概览

45 个门店的特征:类型和大小。CSV 数据,涵盖了指定训练日期的与门店、部门以及本地活动相关的信息,例如燃油价格、消费者价格指数、失业率等。CSV

过去的训练数据时间跨度为 2010 年 2 月 5 日至 2012 年 11 月 1 日。

我需要预测的特征是每周销售额(Weekly Sales),输入数据包括门店标识(Store identification)、部门标识(Dept identification)、日期(Date)和是否为节假日(IsHoliday)。

门店日期每周销售额节假日标志温度燃油价格CPI失业
1########1653691053.313.573311.09658.106
1########1651957138.513.558311.35338.106
1########1611968039.933.515311.38918.106
1########1509738056.633.561311.31968.106
1########1555807056.53.635311.35018.106
1########1539553057.793.667311.38068.106
1########1573516055.583.73311.31568.106
1########1505530051.553.733311.0188.106
1########1595968063.373.719310.83057.808
1########1555519065.863.77310.63397.808
1########1566058066.333.808310.58877.808
1########1391356065.853.795310.53917.808
1########1535101067.513.78310.38957.808
1########1603955073.553.835310.357.808
1########1595353075.783.855310.33757.808
1########1399663076.553.836310.61717.808
1########1533070080.553.759310.89687.808
1########1615535080.693.705311.17657.808

问题识别

每周销售额是一个带有标签的连续数值特征。这是一个回归问题,属于监督机器学习的一种。

项目概述

  1. 数据准备
  2. 探索性数据分析(EDA)
  3. 训练模型准备
  4. 实施训练模型
  5. 模型验证与评估
  6. 超参数调整
  7. 最佳模型选择
  8. 预测与分析

1. 数据预处理

清理、转换和编码类别变量以准备历史零售销售数据。进行特征选择和特征工程。

已完成以下预处理活动。

  • 使用 pandas merge,将数据框与训练数据和测试数据合并。
  • 将布尔特征转换为零和一

// 检查是否存在缺失值或 NaN 值

MarkDown(1-5),包含沃尔玛促销降价的匿名化数据,是唯一缺少值的特征。MarkDown 数据并非对所有零售商都可用,并且仅在 2011 年 11 月之后购买时提供。NA 用于表示任何缺失值。在这些列中,我已将 0 替换了 nan 值。

特点

  • 我提取了 Date 列,并从中提取了 WeekOfYear、DayOfWeek、DayOfMonth、Month、Year 和 Quarter;
  • 我创建了一个名为 MarkDown 的新列,它是所有 MarkDown(1-5) 列的总和,然后删除了这五个列。
  • 由于节假日周的销售额可能高于非节假日周,因此我已将 IsHoliday 列的值更改为 1,以包含联邦和国家节假日。
  • 在节假日期间,沃尔玛甚至可能提供特价促销。

输出

因变量每周销售额R 平方0.933
模型OLS调整后的 R 平方0.932
方法最小二乘法F 统计量958.4
日期2022 年 3 月 11 日,星期五F 统计量的概率0.00
时间20:20:31对数似然-63430.
观测数量4762AIC1.270e+05
残差自由度4693BIC1.274e+05
模型自由度68  
协方差类型非稳健  

源代码

输出

Dropped Features -->  ['CPI', 'Unemployment', 'Fuel_Price', 'weekday_4', 'month_7', 'Store_7', 'Temperature', 'month_12', 'Store_43', 'year_2012', 'Store_30', 'month_2', 'month_11', 'Store_16', 'month_5', 'Store_25', 'Store_29', 'month_10', 'Store_17', 'Holiday_Flag', 'Store_18', 'year_2011', 'Store_19', 'month_9', 'Store_20', 'Store_8', 'Store_34', 'Store_15', 'Store_22', 'month_6', 'Store_21', 'Store_35', 'Store_14', 'Store_13', 'Store_45', 'Store_27', 'month_3', 'weekday_1', 'Store_23', 'Store_44', 'Store_42', 'Store_11', 'weekday_5', 'Store_39', 'weekday_2', 'weekday_3', 'Store_24', 'Store_41', 'Store_40', 'Store_10', 'Store_36', 'Store_9', 'month_4', 'Store_2', 'Store_3', 'Store_6']

2. 探索性数据分析(EDA)

相关矩阵的热力图示例

根据此热力图,Size 和 Dept 与每周销售额(Weekly Sales)的关联度最高。

年度周销售额对比

所有三年的节假日期间都有显著增长

年度月销售额对比

正如预期的那样,11 月和 12 月的每周销售额最高。

月日销售额对比

圣诞节期间,每周销售额与季度相比大幅增长。

正如预期的那样,第四季度的平均销售额最高。

每周平均销售额与门店对比

每周销售额与门店对比:平均每周销售额最高的前 5 家门店是 20、4、14、13 和 2。A 类门店的每周销售额似乎高于 B 类和 C 类门店。

每周销售额与温度对比

每周销售额与节假日标志对比

节假日期间出现高每周销售额异常值的周比非节假日期间更常见。令人欣喜的温度(介于 30 到 70 华氏度之间)下似乎记录了较高的每周销售额。

每周销售额与门店类型和大小对比

考虑到 A 类门店是两个沃尔玛零售店中规模较大的,因此它们拥有最高的每周销售额是合乎情理的。

部门与每周销售额对比

表现最好的部门是 95、38、40、92 和 90。

3. 准备训练模型

在此部分,我完成了以下任务。

  • 插补、缩放和编码;
  • 识别数值型和类别型列;
  • 识别输入和目标列;
  • 拆分为训练集和验证集(75-25 拆分);

4. 实现和训练 ML 模型

ML 模型基线:线性模型

考虑到这是一个回归问题,我的基线机器学习模型将是 LinearRegression() 模型。为了充分比较 Sklearn 提供的所有线性模型的性能,我还训练了 Ridge、Lasso、ElasticNet 和 SGDRegressor。

我编写了一个名为 Try_linear_models(model) 的函数,该函数接受模型作为输入,在训练数据上进行训练,并输出训练和验证的均方根误差。

[训练和验证得分]

我们看到,线性和逻辑模型都获得了约 20,000 的 RMSE 得分。考虑到约 20,000 的每周销售额大约处于第 75 百分位数,这对于我们的基线 ML 模型来说表现非常差。由于模型 R2 分数如此之低,我认为没有必要进一步研究线性模型。

组合模型

为了确定哪些模型最初具有更高的评估分数,我使用默认设置训练了随机森林、梯度提升、Adaboost、XGBoost 和 LightGBM 等集成模型。Try_ensemble_methods() 是我编写的一个函数,它接受模型作为输入并输出评估指标。

5. 模型评估

我将对随机森林、XGBoost 和 LightGBM 进行超参数调优,因为它们是基于评估分数表现最好的三个模型。AdaBoost 的运行水平与线性模型相当,都处于不理想的水平。

影响每周销售额的两个关键因素是部门(Dept)和大小(Size)。

6. 超参数调优

我们使用加权平均绝对方差(WMAE)来评估超参数调整。

我创建了一个字典,其中包含“具有超参数和待测值的模型”。

通过 test_params() 和 test_param_and_plot() 函数对每个超参数训练了模型,这些函数还返回了每次运行的评估得分。

随机森林超参数调整的过拟合曲线如下

Predicting Walmart Sales with Python (Machine Learning Models)

max_depth 的调优

Predicting Walmart Sales with Python (Machine Learning Models)

n_estimators 的调优

Predicting Walmart Sales with Python (Machine Learning Models)

min_samples_split 的调优

XGBoost 超参数调优的过拟合曲线如下:

Predicting Walmart Sales with Python (Machine Learning Models)

max_depth 的调优

我发现,经过超参数调整后,随机森林是该数据上表现最好的模型。

7. 最佳模型选择

在超参数调整方面,随机森林表现最好;它产生了最高的验证分数,约为 2000。我还使用了 GridSearchCV 来获取最适合数据的随机森林模型。

验证 WMAE:$ 1985

8. 测试预测与提交

当 n_estimators = 200 且最大深度 = 25 时,随机森林是众多提交模型中表现最好的模型。凭借近 4000 的公开分数,我在竞赛中的排名进入了前 50%。

在所有训练的模型中,n_estimators = 200 且最大深度 = 25 的随机森林(RF)回归器是最佳模型。

结论

ARIMA 等时间序列建模方法可用于改进销售预测。所有顶级的 Kaggle 预测都以某种方式使用了时间序列分析。通过这样做,可以改进本项目。时间序列预测的应用包括股票价格预测、天气预报、销售和需求预测、在线流量预测等。时间序列建模是机器学习的一个重要领域,越来越多的企业正在以某种方式使用它。因此,对于有志成为数据科学家的个人来说,理解这个概念至关重要。