标签:噪声 ast ceshi 三级 不能 就是 指定 转变 bit
https://blog.csdn.net/bitcs_zt/article/details/79256688
该项比赛1月15日就已经结赛了,但由于之后进入期末,备考花费了大量的时间,没来得及整理相关内容。现在终于有时间好好回顾比赛,并对这次比赛的过程进行记录。
本次比赛是预测商品销量,给出的训练数据为<单位销量,日期,商店ID,商品ID,推销活动标签>,其中单位销量是待预测值,基本上属于回归问题。同时给出的额外数据表有:
值得注意的是,同一商品可能在不同的商店均有销售,而最后的测试数据为<日期,商店ID,商品ID,推销活动标签>,我们需要预测的是某商品在指定商店在某天的销量。训练数据给出了从2013年-2017年8月15日近一千余天的数据条目,每一天都包含各类商品在各个商店的数据条路,而很多商品只在某一些时间阶段出现过。测试数据需要预测的是2017年8月16日—31日销量情况。这就使得数据的组织十分重要。
和以前比赛一样,我还是在比赛过半左右的时间参与的比赛,这个时间参加,基本上forum已经有了解决该题的大方向,不至于跑偏。由于还要兼顾课业,从最开始慢慢实验测试是不太可能了,这也是kaggle比赛比较友好的地方,forum在比赛的各个时段都会有kaggler的集思广益,使得我们这类以学习为目的的人能用最小的成本学到最多的东西。
如上所述,如何组织数据至关重要。刚参赛时,我在做了简单的EDA后,发现数据并无特别的规律,原始训练数据如下(数据量巨大,只取了2017年的):
可以看到,在如上这种数据组织方式下,难以“下手”,特征数目太少不可能直接用模型训练,且其中的日期、ID等特征都不是数值型数据。思考几日后,在forum上发现了一个帖子Ceshine Lee-LGBM Starter
,将数据按<商店ID、商品ID、日期>三级索引形式重新组织,得到数据表如下:
此时每个数据条目便有了真实意义——某商店的某商品在一段时间内的销量。如此将该问题转变为了类似“股票价格预测”的问题,这与我们的最终目标“预测某商店的某商品在2017年8月16日-31日的销量”也能对应上。该文还做出了其他一些尝试:抽取了销量均值作为特征来训练LGBM,针对16日-31日的每一天分别训练模型进行预测,选取与16日-31日有相同周期的(16日为周三)作为训练数据。最后排名靠前的选手基本都参照了该文的思想。
利用机器学习来解决实际问题,关键无外乎四点,对应到本题有如下分析:
data、feature、model、ensemble四个部分不可能严格意义上串行工作,有可能选用了model后发现不合适,更换model的同时数据可能也需要重新整理。这需要我们建立良好的pipeline,减少反复调整带来的额外工作量,并记录好重要步骤作log。
先将原始数据转变为销量序列。由于时间相关序列在训练集和验证集的组织上需要严格根据时间决定,给出2017年5-8月日历如下:
可以看到,待预测日为16-31共计16日,要注意到以周三为起点这一周期信息,并且要最大化地利用信息。由于之前做EDA,单个商品没有反映出长期的周期性,故可以认为,训练集越接近待预测日,整合越多的信息,越能准确预测。比如选择7.26-8.9的每个商品的价格作为训练集标签,7.26之前的价格数据抽取feature作训练集,这段时间是符合周期分布(周三开始、周四结束)下时间上最接近测试集的16日,将其称为一个batch。考虑获取多个batch形成训练集,可以选取7.5-7.20、7.12-7.27、7.26-8.9三个batch,即间隔一周或若干周选取一个batch,保持了周期性。虽然batch之间可能有一定的重复性,但这是必要的。一来使数据量增多,模型不容易过拟合,二来针对某个商品,我们有了若干个数据条目(一个条目即为上图中某个商店的某个商品在一段时间内的销量),无论是使用树模型还是NN,这都能使模型更加robust。
实验中batch为6-15不等,batch之间间隔试了1、2、4周。使用7.26-8.9做validation set,在比赛后期,利用带validation set来确定模型训练轮数R(validation set上准确率确定是否结束训练),再将validation set的数据加入到training set,这样我们可以利用更靠近8.16的数据,实际上也这样做也确实带来了准确率的提升。
针对某一batch,比如7.26-8.9,根据商品价格序列抽取如下特征:
由于在比赛过程中常想到新的特征,加入特征又需要重新实验,耗时耗力。故在比赛之初,就应该尽量把特征工程做好,同时建好pipeline,以减小增删特征重复试验带来的精力损耗。同时要结合树模型所产生的feature importance判断特征好坏。Data和Feature的实验在比赛早期要尽可能做完善,虽然不可能尽善尽美,一定要建好pipeline,血的教训!!!比赛进行到后期时,model和ensemble也要做实验时,在jupyter里写代码的弊端就体现出来了,往往上下翻阅很久。良好的pipeline会让功能架构清晰很多。
其实刚看到时间序列模型是想用RNN的,找了forum里面一个LSTM网络跑了一下,笔记本跑了一晚上,成本太高了,就放弃了。主要还是使用的树模型。这次尝试了LGBM,据说是比XGBoost快,这次时间紧,也就没做对比。总的来说还是挺好用的,速度也很快。由于比赛过程中,除了模型调参还要调整data和feature,所以最终跑出来的单个模型也没有表现特别好的。而且在比赛后期由于提交次数限制,很多模型调参只是根据本地cv判别了优劣,而这次比赛的本地cv和提交结果不是完全同步提升的,可能错过了一些潜在的好模型,这也是以后要注意的。对于LGBM的调参还是太稚嫩了,只能说多经历多学习吧。
还使用了CatBoost,据说对类别型数据支持较好,但应该是我还不太了解一些参数的意义,只是简单地做了一些设置,最终该模型表现效果不如LGBM,且速度比较慢。
比赛初始还尝试用auto encoder,效果不理想就放弃了。花费时间成本也比较高。理论上来说直接调参RNN是更好的选择,上次比赛优胜选手使用了该模型,自己也想试试。也算尝试了一下吧。
时间缘故,也没有时间做两层的ensemble了,只是将结果进行了简单的加权bagging。最终参与bagging的模型有7个LGBM+1个CatBoost+1个Median-based。最后放榜的成绩只有小数点后三位,有很多简单的bagging和单个模型与最终提交的bagging是一样的成绩,也无法得知孰优孰劣,本着bagging模型多样性的原则,还是选择了一个较多模型的bagging。
结赛后,也看了forum上很多排名靠前选手给出的解决办法。很多使用了NN based的方法,不过多数都来自于之前一些时间序列比赛的经验,也说明了经验对于神经网络的设计构建是多么的重要。不过让人欣慰的是排名第1的选手给出的得分最高的模型是LGBM,结合了很好的特征工程。让我这种现阶段没有DNN实验条件的人有了很多希冀。
总结下从这个比赛学到的东西:
待提高之处:
给出赛后排名靠前选手的解决方案汇总:
Top Solutions
以上是这次比赛我自己方面的一些总结,一分耕耘一分收获吧。最后40/1675的成绩,获了一枚银牌,心里也很开心。以后还是多打比赛,多写代码,多看forum,多学东西。
但做好事,不问前程。
--------------------- 本文来自 ZSYGOOOD 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/bitcs_zt/article/details/79256688?utm_source=copy
kaggle-Corporación Favorita Grocery Sales Forecasting
标签:噪声 ast ceshi 三级 不能 就是 指定 转变 bit
原文地址:https://www.cnblogs.com/DjangoBlog/p/9706728.html