京东赛告一段落。作为一个菜菜鸟,虽然无缘前十,但是也算是有一点小感悟和一些对数据挖掘的认知。毕竟这是第一次接触比较接近实际工程中的数据,而且是时间序列相关的数据。
一. 数据集的划分
在做京东赛的时候,第一眼看到数据集就是懵的,感觉和房屋预测的咋一点都不一样·········训练集也没有,测试集也没有,而且还有好多个表,咋往一块拼呢·········后来看了wepon在天池优惠券核销预测的代码后,才渐渐有了一点思路,在这里感谢wepon大神,代码在这里。
对于我过去接触过的机器学习问题,训练集就是原始数据,测试集就是新数据。我在原始数据和新数据中,挖掘出相同维的特征,区别就是原始数据有标签,而新数据没有标签。用有标签的数据学习出一个模型,再应用到具有相同特征维的没有标签的数据上,预测得到结果。
但对于时序数据来说,就不一样了。
时间序列预测的核心思想是:用过去时间里的数据预测未来时间里的Target。
也就是说,在构建特征的时候,我需要所有的历史数据构建预测特征。有时候,也会有待预测时间段的一些特征,比如在天池的O2O赛中(不过这也是一个leakage,在实际工程中,是不会得到这个数据的)。将历史数据的预测特征,和新数据的一些预测特征结合起来,得到完整的所需要的特征,然后放到模型里面,得到预测结果。
还有一个比较重要的部分就是,负样本的建立。在这里的数据,所有买过的都算是正样本,但是还需要负样本。我这里就是自己造了个负样本。按照1:1的比例,对所有数据,随机进行1-2天的前后移动,然后把这些数据里的错误数据删去(错误数据:在这个时间里有过购买行为的为错误的数据)。由此得到负样本。
有了特征,那我们的target怎么找?
这里我们就要从历史数据中构建target.
一个比较常用的方法就是滑窗。
二. 滑窗与模型构建
通过时间滑窗,人为的构造target,让模型进行学习。也就是对于历史数据,再人为设置历史窗口和未来窗口。怎么做呢?具体示意图如下:
(图片来源为这里,这篇讲的也挺好的,对我理解时间序列起了很大帮助)
假如有1-6月的历史数据,要预测7月份的销售量
1,2,3月份提取预测特征A,4月份提取预测特征B,并提取预测target,也就是销售量
2,3,4月份提取预测特征A,5月份提取预测特征B,并提取预测的target。
以此类推,以一个月为周期向前滚动。
最后呢,我把所有提取到的特征,也就是每个窗口的预测特征A+预测特征B作为训练集,所有的预测target作为训练集的target。用这些数据训练模型。
(他们之间的连接是按列连接,并非按行连接。也就是说,不管是哪段时间窗口,我提取到的特征维度都是一样的,不同的时间窗口,相当于只是增加了我的训练实例(instance))
对于新数据,我的输入为(当前例子中)4,5,6月份的预测特征A加上7月份的预测特征B,整体构成特征集合。输入到模型中,得到预测结果。
按我的理解,时间滑窗相当于增加了样本量,并且通过对不同时间段的采样,可以得到更丰富的特征。
三. 特征工程的构建
感觉在数据比赛中,最最关键的还是特征。有时候模型可以稍微弱一点,甚至是单模型,也可以优于xgboost这种提升模型。比如今年的IJCAI中的阿里妈妈算法大赛,夺冠的解决方案就是单模型的·····膜拜一下大神。
在这一块儿还差的很远。而且,京东赛分数不高的原因也是因为特征选的太弱,不够多。但是有几个思路吧:
1. 皮尔森相关系数的应用,可以看看特征和target之间的相关程度。太弱的或者可以直接抛弃。
2. 选择一些强相关性的特征,通过一些个运算啊什么的构造一些新的特征。
3. 结合业务场景,构造一些业务中常用的一些个指标。
4. 对于一些特殊日期的关注。比如电商销售额预测,双十一双十二的数据肯定是异于平常的,此时可以对他进行单独的预测,或者和平时的进行加权,等(这可能是数据预处理阶段的工作)
5. 构建了一系列的特征,其实并非所有的都那么重要,可以对特征进行选择,去掉冗余特征。比如说,可以用xgboost方法或者GBDT这种有feature_importances方法(或者score这种)的,对训练完的模型的特征根据评分的不同进行排序,以此选择一些较好的特征。
大致就是这些了。算法之路,漫漫其修远兮,吾将上下而求索(拽一下·····)。