1. 说明
前一段参加了天池的“盐城汽车上牌量预测“比赛。第一次面对大规模的时序问题,从比赛的过程,到赛后各位大佬的算法分享,收获很多。也将解决该类问题的套路在此总结一下。
本篇是总述,其中提到的具体算法,如:加窗,ARIMA,傅里叶/小波变换,LSTM等等将在本系列的后续文章中一一详述。
2. 问题描述
上牌量预测是一个典型的时序问题,且数据简单清晰,以复赛A榜数据为例,它提供了前3年的10种品牌汽车每天的上牌量,预测未来半年中每天的各品牌的上牌量。
提供的信息只有之前的上牌量,日期数据和星期几,是一个单变量的预测问题(暂不计各品牌间的相互影响),比较困难的是:它不是预测一天,而是预测几百天,有些时序模型无法使用。
3. 步骤
对比一下自己和大家的解决方案,基本都可以拆解成以下步骤
(1) 还原日期
比赛数据对日期进行了脱敏处理,没给具体年月日,但提供了周几的信息,其中有些节假日上牌量为0的也没有给出对应记录。第一步大家都补全了日期,加入了真实日期,和节假日信息。
这里介绍两个相关阴历的时间转换库:
chinese_calendar,Lunar-Solar-Calendar-Converter
(2) 从日期中提取信息
这是各显神通的环节,大家根据自各经验,提取了各种各样的特征,总结如下:
假期长度、调休日期、与节假日的时间距离;
某年中的第几个月,某年有的第几周,某月中的第几周,某月中的第几日,某年中的第几日(阴历/阳历分别取),正数/倒数第几个工作日。
(3) 提取周期信息
对于周期提取,基本有两种做法,一种是手工计算出同比,环比,往期数据,直接加入Feature,然后用GBDT生成决策。另一种是用ARIMA预测出大致的周期趋势,然后用GBDT描述其余细节。
i. 手工加入周期数据
有一些方案完全没使用趋势和周期算法,排名也挺靠前的,其原因是,他们直接把周期和统计数据做成了特征,比如:用shift()把前N天的上牌量做为当天的特征,用rolling()将前N天均值作为当天特征,将阴历/阳历的去年同期(月、周)数据作为当期特征,环比的最大值,最小值,分位数等等。这种方法的好处是模型可以同时处理维度的各种特征,美中不足是可能损失一些对趋势的预测。
ii. 算法预测周期和趋势数据
此类方案以ARIMA代表,ARIMA,小波变换,线性拟合,它们是解决时序问题的传统方法。再与GBDT算法相结合,处理一些不能被周期性识别的细节。这种方法的优点是兼顾整体和细节,问题时在预测长周期时,后期有严重的衰减。
(4) 梯度下降决策树
几乎所有的人都使用了梯度下降决策树(GBDT)类算法和交叉验证(CV),值得注意的是,有一些特征需要处理成“类别”而非“数据”,比如“月份”,“周几”,“品牌”等等,否则很影响效果。
4. 原理
对于时序问题,一般可以拆解为:趋势+周期+突发事件。
(1) 趋势
一般需要先拟合趋势,比如使用:滑动平均模型,指数平均模型,线性回归等等。其中需要注意的是拐点的识别(不限于此题),比如一些股票缓涨急跌,即它在上升和下降的趋势中规律完全不同,则需要分段处理。另外我理解,趋势有含有两部分,一部分和均值相关,一部分和方差相关。均值描述位置的高低,方差描述波动的大小。
(2) 周期
这里指的周期是大周期,中周期,小周期,相互交错,包含的情况。比如年内变化,周内变化都呈明显周期性。一般可使用:季节模型,小波/傅里叶变换,差分周期等等。我觉得ARIMA也可算做一种周期性工具,它的主旨也是用过去的N项预测未来。
周期与趋势的组合,又有交乘和叠加等不同方式。
(3) 突发事件
现在一般都用机器学习的工具处理突发事件和结果的关系,比如随机森林,梯度下降决策树,还可能用到关联规则等等。
(4) 扩展
不只是时序问题,其它的机器学习问题也是一样,比如说大分类包含小分类这种情况,也类似于周期。都需要去考虑统计特征。