Kaggle Predict Future Sales 竞赛报告
唐健 [email protected] 2020-07-31
摘要
Kaggle 上的Predict Future Sales竞赛提供了俄罗斯1C company 近3年来的销售数据,其要求是使用这些数据进行建模,并预测接下来一个月里的每个商店的每种商品的销售量。这篇报告介绍了如何参加这个比赛,给出了一个如何使用R语言进行数据清洗,特征工程抽取,模型构建的全过程。截止到2020/7/31,模型在竞赛中提交了15次,取得的最终分数是0.899946,整体排名11%。
竞赛介绍
参加这个比赛是几乎无门槛的,我们可以直接访问竞赛的官网地址【1】,注册一个kaggle账号然后参与近来。
竞赛提供的数据集为6个.csv文件,大小为近100M,分别包括了指定的训练集,指定的测试集,一个标准提交样本,商店信息,商品信息,商品分类信息。
- 训练集中包括精确到日的时间,月份编号,商店ID,商品ID,商品价格,商品当日销售量。
- 测试集中包括定位ID,商店ID,商品ID。
- 标准提交样本中包括定位ID,未来一个月的预测销售量。
- 商店信息中包括商店ID,商店名称(俄语)。
- 商品信息中包括商品名(俄语),商品ID,商品分类ID。
- 商品分类信息中包括商品分类编号,商品分类ID。
数据处理
缺失值处理
首先进行缺失值检测。缺失值处理的策略有很多:
直接删除(合适本场景):数据量很大的场景,如果有缺失值,有事可以选择直接去掉。
均值填补(不合适),
分类均值填补(合适),
延续最后观测值(合适),
多重插补(不合适)
本例子中没有缺失值,所以无需处理。
异常值处理
在进行数据分析前,通过简单的可视化手段,如箱型图,直方图,对数据的分布进行一个初步的理解是很有必要的。如果我们发现了一些异常值,一个简单有效的策略是将他们从数据集中去除,有些时候我们可能会使用一些其他的手段,如将它们另归为一类,或者单独考虑等。
在这个案子中,下图展示了销量和日销售量的分布情况。我们发现一些商品有着远高于平均的销量和价格,我们采用简单的策略,即将销量高于1000,价格高于150000的数据删掉。
值得一提的是,本案中的销售量,价格等理应是严格正数,但数据集中却有出现商品价格,销售量为负数的情况,这可能是由于赠送,赔偿等情况引起的。这里采用的策略是将负数价格的数据删掉,将销售量为负数的数据置为销售量为0。
特征抽取思路
响应变量是一个月的销售量,关于预测变量,首先我们应该尽可能多的使用/制造/抽象出更多的预测变量,这是一个高手工要求的过程,而且我们会在后续的建模过程中不断修整,以得到更高的模型分数。
我们可以直接使用的有的:价格,商品号,商品种类号,商店种类号,销量。
一些值得考虑的包括:月份,前N天/月的销售量,销量,价格,价格波动,商品销售额,商店销售额等等。
模型选取思路
GLM及其衍生模型,有较强的离群值和较多的0值,直接用不太合适,可以考虑一下如何进行转换。
神经网络,特征量是不够的,考虑抽象化特征?这个方式可行但由于使用的较少,后面可以考虑。
回归树,特征量基本够用,使用集成学习思路,加入随机性,XGBoost是我们选择使用的。
特征抽取细节
特征抽取是一个高手工要求的过程,并且会更具模型表现不断返回修正。这里特征工程着重参考了一些其他参赛者的成熟思路【2】【3】。
- 商店商品价格:按照商店+商品进行分组,统计每个组内的价格的最大值,最小值,平均值,中位数,标准差。
- 商品价格:和1相似,不同的是仅按照商品分组,不考虑商店的区分。
- 上个月的销售量,价格,销售额及其滞后值:按照商店+商品+月份分组,统计前一个月的销售量,价格和销售额。对这三者分别计算其往前三个月的值(滞后值),并计算当月+前两个月的均值。
- 月销售量:按照商品+商店分组,统计商品无任何销售量的月份数量,统计商品月销售量的最小值,最大值,均值,中位数和方差。
- 商品数量:按照商店分组,统计这个商店内所有商品的数量。
- 同一类商品中,最大月销售量:按照商店+商品类别分组,统计同一类别商品中的最大销售量
- 价格走势:统计商品前一个月价格和历史最大,均值,中位数价格的差值。
- 销量走势:统计商品前一个月销量和历史最大,均值,中位数销量的差值。
- 销售额走势:统计商品前一个月销售额和历史最大,均值,中位数销售额的差值。
- 销售时间区间:统计商品的销售月份长度。
- 无销售量时间区间:统计商品无销售量月份长度。
- 是否是当月新品:统计商品是否是当月新品,及销售时间区间长度为0
- 月份:将月份编号转为1-12个具体月份。
- 商店ID:数据中有,直接取。
- 商品ID:数据中有,直接取。
- 商品分类ID:数据中有,直接取。
- 月份编号:数据中有,直接取。
模型构建
训练,测试,预测数据集构建
使用月份编号32做训练集,33做测试集,34做预测集合。响应变量是月销售量,预测变量是特征抽取细节章节中描述的那些特征。
模型选用XGBoost, 使用xgb.cv,多线程模式,100轮,flod=5进行训练,,模型具体参数这里不一一列出。
性能表现
训练集(左)和测试集(右)RMSE分别是:
Kaggle最近五次提交(共提交15次)及其分数如下图所示:
Kaggle排名如下图所示:
局限性和一些想法
模型选择的局限性:诸如神经网络和GLM衍生模型也是值得考虑的模型选择,但因为时间限制我没有来得及尝试。
模型参数的局限性:XGBoost模型参数的设置很大程度上直接参考了一些成熟作品的参数,由于对算法本身的了解不足和网站的提交次数限制,模型的参数仍然值得继续探索。
特征工程的局限性:在查阅了一些俄罗斯人写的notes之后,发现商店名成中包含了诸如城市,地区,商店类型等信息,它们可以拆开来用来做为特征,但我不懂俄语,所以没办法这样做,而是直接使用了商店ID。同理,分类名成中包含着商品的分类信息,如日用品,玩具等,可以进一步进行特征抽取,但我不懂俄语没有这样做。
引用
【1】https://www.kaggle.com/c/competitive-data-science-predict-future-sales/overview
【2】https://www.kaggle.com/junota/predict-future-sales-naive-forecasting-xgboost
【3】https://www.kaggle.com/gordotron85/future-sales-xgboost-top-3