机器学习与时间序列预测

96 爱斯翠摩鸡 关注

2018.03.15 14:02* 字数 2186 阅读 2711评论 8喜欢 9

前言

在所有的预测问题里面,时间序列预测最让我头疼。

做时间序列预测,传统模型最简便,比如Exponential Smoothing和ARIMA。但这些模型一次只能对一组时间序列做预测,比如预测某个品牌下某家店的未来销售额。

而现实中需要面对的任务更多是:预测某个品牌下每家店的未来销售额。也就是说,如果这个品牌在某个地区一共有100家店,那我们就需要给出这100家店分别对应的销售额预测值。

这个时候如果再用传统模型,显然不合适,毕竟有多少家店就要建多少个模型,太累。

而且在大数据时代,我们面对的数据往往都是高维的,如果仅使用这些传统方法,很多额外的有用信息可能会错过。

所以,如果能用机器学习算法对这“100家店”一起建模,那么整个预测过程就会高效很多。

但是,用机器学习算法做时间序列预测,处理的数据会变得很tricky。对于普通的截面数据,在构建特征和分割数据(比如做K-fold CV)的时候不需要考虑时间窗口。而对于时间序列,时间必须考虑在内,否则模型基本无效。因此在数据处理上,后者的复杂度比前者要大。

之前在处理时间序列的时候,一直没太想明白该怎么做,最近观摩了几个时间序列预测竞赛冠军分享的代码,颇有收获,这里总结一下他们的建模思路,以便自己日后再碰到类似问题的时候,不要脑抽。

时间序列预测模型建模思路

1. 初始数据集

一开始拿到的数据可能是分好训练集、测试集的,也可能是没分好的。这里我按照竞赛的情况假设一开始的数据集分有训练集和测试集。

对于时间序列数据来说,训练集即为历史数据,测试集即为新数据。历史数据对应的时间均在时间分割点之前(如2018年以前某品牌每家店每天的销售数据),新数据对应的时间均在分割点之后(如2018年以后某品牌每家店每天的销售数据)。

历史数据和新数据均包含N维信息(如某品牌每家店的地理位置、销售的商品信息等),但前者比后者多一列数据:Target,即要预测的对象,如销售额。

基于给出的数据,我们的预测任务是:根据已有数据,预测测试集的Target(如,根据某品牌每家店2018年以前的历史销售情况,预测每家店2018年1月份头15天的销售额)。

2. 数据处理

在构建预测特征上,截面数据和时间序列数据遵循的逻辑截然不同。下面两张图分别是二者的数据处理逻辑示意图。

首先来看针对截面数据的数据处理思路。

对于截面数据来说,训练集数据和测试集数据在时间维度上没有区别,二者唯一的区别是前者包含要预测的目标变量,而后者没有该目标变量。

一般来说,在做完数据清洗之后,我们用“N维数据”来分别给训练集、测试集构建M维预测特征(维度相同),然后用机器学习算法在训练集的预测特征和Target上训练模型,最后通过训练出的模型和测试集的预测特征来计算预测结果(测试集的Target)。

此外,为了给模型调优,我们一般还需要从训练集里面随机分割一部分出来做验证集。

而时间序列的处理思路则有所不同。

时间序列预测的核心思想是:用过去时间里的数据预测未来时间里的Target。

所以,在构建模型的时候,所有过去时间里的数据(训练集里的N维数据和Target,如2018年以前每家店的地理信息、所卖商品信息、日销售额等)都应该拿来构建预测特征。

而新数据本身的N维数据(如2018年1月头15天每家店的地理信息、所卖商品信息等)也应该拿来构建预测特征。

前者是历史特征(对应图上的预测特征A),后者是未来特征(对应图上的预测特征B)。二者合起来构成总预测特征集合。

最后,用预测模型和这个总的预测特征集合来预测未来Target(如未来销售额)。

看到这里,一个问题就产生了:既然所有的数据都拿来构建预测特征了,那预测模型从哪里来?没有Target数据,模型该怎么构建?

你可能会说,那就去找Target呗。对,没有错。但这里需要注意,我们要找的不是未来时间下的Target(毕竟未来的事还没发生,根本无从找起),而是从过去时间里构造“未来的”Target,从而完成模型的构建。这是在处理时间序列上,逻辑最绕的地方。

3. 模型构建

用机器学习算法构造时间序列预测模型,关键的思路在于,通过时间滑窗,人为地构造“未来”Target,来给算法进行学习。

有点绕,请看下面的示意图。

和之前一样,从时间的角度上来看,我们有历史数据,和新数据。但这里,我们不能简单地把历史数据作为训练集、把新数据作为测试集。

怎么做呢。

首先,在历史数据上,我们通过截取不同时间窗口的数据来构造一组或几组数据。比如,我的历史数据是2017年 1月到12月每家店每天的销售数据,那么我可以截取3组数据(见上图的深绿、浅绿部分):2017年1月到10月的数据、2017年2月到11月的数据、2017年3月到12月的数据。

然后,人为地给每组数据划分历史窗口(对应上图的深绿色部分)和未来窗口(对应上图的浅绿色部分)。比如,对于2017年1月到10月的数据,我把1月到9月作为历史窗口、10月作为未来窗口,以此类推。

接着,分别给每组数据构建预测特征,包括历史特征(预测特征A)和未来特征(预测特征B)。而此时,每组数据还有预测Target。

这个时候,我们把得到的所有预测特征(我的例子里是三组预测特征)都合并起来作为训练集特征、把所有预测Target(我的例子里是三组预测Target)合并起来作为训练集Target,之后就可以构建机器学习模型了。

有了训练集和训练模型,还差测试集。测试集的构建遵循之前的数据处理逻辑,拿历史数据构建历史特征,拿新数据构建未来特征,然后把这些特征加入到从训练集上训练出的预测模型中去,即可得到任务需要的最终预测值。

这里需要注意,划多少个时间窗口因数据而异。此外,数据的历史窗口(图上深绿部分)和未来窗口(图上浅绿部分)可以是定长也可以是变长,看具体情况。

以上就是我最近总结出的用机器学习算法构建时间序列预测模型的建模思路。

小礼物走一走,来简书关注我

赞赏支持

 日记本

© 著作权归作者所有

举报文章

96关注爱斯翠摩鸡

写了 40994 字,被 24 人关注,获得了 29 个喜欢

喜欢

 

9

   更多分享

Web note ad 1

登录 后发表评论

8条评论 只看作者

按时间倒序按时间正序

 小鱼儿_1876

5楼 · 2018.08.24 17:31

没看懂,拿到模型之后,特征B从哪里来。。。 未来有啥特征。

  回复

 

Yessica宏业

 例如 你要预测某一天的销量,那一天是一周的第几天,一个月的第几周,哪一个月等特征就是未来的特征

2018.08.28 22:22  回复

 添加新评论

 Yessica宏业

4楼 · 2018.08.20 15:30

请问能不能分享一下 观摩的几个时间序列预测竞赛冠军分享的代码或文档~

  回复

 

爱斯翠摩鸡

 https://github.com/wepe/O2O-Coupon-Usage-Forecast

2018.09.04 10:51  回复

 添加新评论

 edwin1993

3楼 · 2018.06.07 21:39

最近在做客户缴费预测,想添加一点时间序列思想进去。读了以后受益匪浅,非常感谢大佬:smile:

  回复

 

爱斯翠摩鸡

 @edwin1993 哈哈不客气 一点小总结 希望有帮助:smile:

2018.06.08 13:26  回复

 添加新评论

 Devi_833d

2楼 · 2018.05.14 11:03

时间序列要保证测试集在训练集时间点之后吧, 文章中的“这个时候,我们把得到的所有预测特征(我的例子里是三组预测特征)都合并起来作为训练集特征、把所有预测Target(我的例子里是三组预测Target)合并起来作为训练集Target“” 会导致部分训练数据在测试集之后吧?

  回复

 

爱斯翠摩鸡

 @Devi_833d 我是这么认为的:这些滑窗数据之所以能合并,是因为我在每组数据上分别构造了“历史”特征和“未来”预测值,也就是说,每一行数据都是用过去的X去预测未来的Y,那这个时候这些数据是可以合并起来、可以当作截面数据那样去用机器学习算法了。可能我确实有欠考虑的地方,但我没太想明白您说的“部分训练数据在测试集之后”具体指的是什么,方便的话您可以说得更详细一些,我们可以探讨一下

 

 

 

 

什么是时间序列:

什么是时间序列?

时间序列是在一定时间间隔内收集的一系列观察结果。时间在这里起着重要的作用。收集到的观测结果取决于收集的时间。

 

比如,在沃尔玛这样的零售商店里,面包的销售将是一个时间序列。销售可以是每日水平,也可以是每小时水平。每天从纽约飞往西班牙的人数是一个时间序列。时间在这里很重要。在圣诞节期间,这个数字与其他日子相比将是巨大的。这就是所谓的季节性。

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐