一些时间序列处理工具包的简单比较(待续)
- 2021 年 6 月 1 日
- AI
时间序列的Python工具很多,但是好用的不多,因为论文需要,调研了几乎全部的star比较高,维护相对积极的python library,这里给出一些简单的总结:
需求:
1’单序列单变量(序列值本身)建模;
2 单序列多变量建模(包括序列值本身,以及其他的一些时变或者时不变变量);
3 多序列单变量建模和多序列多变量建模
多序列指数据中包含了多个独立的序列,例如不同店铺的不同商品都存在一个自身的时间序列数据,这也是最常见的问题形式。
关于单序列的问题,单序列问题本身的数据量往往不大,尤其是电商,即使单序列的长度很长,一般来说也就取最近一段时间的数据来进行建模,因为序列数据本身的趋势、周期、固有值也是发生变化的,例如固有值会随着通货膨胀,经济周期等因素从而发生变化(我大一那会儿门口的山东煎饼两块钱一个,现在最便宜的都要五块钱了),趋势(比如股票指数,很明显其上升、下降和平稳变化的趋势差异是很大的),周期(520,618,11.11各种新的节日会带来非常明显的新周期),因此往往单序列建模不会取太过久远的数据,除非数据是秒,分钟级别的,如果按照3~5年来取数据(这也是我所处理过的时序问题里最常见的取法了,在kaggle上的序列比赛里甚至给定的数据集都没有超过5年以上的),天级别(常见的数据的序列值的level),个人浅见,在一些常规的供应链,电商场景下,比较少有低于天级别的历史数据存储,高频交易有可能存储分钟甚至秒级别的数据,但是这个就在讨论之外了。
所以即使按照五年来测算,单序列也就5*365=1825条数据,更不用说很多商品压根就取不到这么长的销量数据,一些冷门商品的销量数据可能也就上百条,这种情况下进行机器学习或者深度学习建模的难度是很大的,样本量实在太少了,举个极端的例子,假设我们的序列数据是这样的:
[1,2,3,4…..1824,1825],即使通过滑窗的方式来构建样本,用能够产生最多样本的滑窗方式来构造,用过去一天预测未来一天,则样本构造为:
[1,2]
[2,3]
[3,4]
…
[1824,1825]
也就1824条的数据,这点样本我在线下测试过两个数据集,一个是web traffic中某个网页的流量数据,数据量接近900条,一个是kaggle的m5的比赛里某个商铺的某个sku的序列数据,为了避免趋势性的影响,使用的单序列基本上没有趋势性,进行单序列建模,测试了经济学模型,xgboost和简单的lstm,可以说xgb和nn的略差,放一部分结果:
这是lightgbm的预测结果,mape=1.9868239292946304
这是holtwinters的预测结果,mape=0.24162530054457074
ets,mape=0.3486683255515128
arima,mape=0.8770316409264396
tbats mape=0.47721204186604005
Prophet mape=0.30538213361067473
复合策略,对趋势,周期分两个模型建模,叠加最近一个周期的简单平均,mape=0.2744438240584007
lightgbm ,mape接近2了。。(机器学习算法这里采用了迭代预测的方式,直接预测和混合预测的方法复杂度太高了,基本上实际应用上不会去考虑,这里预测的是为了63天的数据,如果使用直接预测或者混合预测的方法则意味着要构建63个lightgbm模型,这种高计算复杂度基本上是不会考虑应用的)
使用线性回归去除趋势之后的lightgbm:
mape=0.42634482052747374
单序列的预测面临的主要问题是小样本问题,其实通过复杂的特征工程构造是有可能提高机器学习或者nn模型的预测结果的,但是个人认为这样做意义不大,nn不用说了,高参数空间,少量数据可能连收敛都不够,而gbdt模型相对来说稳定性好一些,但是面对趋势是没有什么好的解决方法的,必须通过一些简单趋势模型来结合lgb一起预测,并且如果周期性很明显则最好也补充一个周期策略模型来一起预测,最后,使用nn来处理单序列预测的问题,我基本上放弃这个方向了。。。希望有人能来打我脸。
言归正传,下面总结一下调研的几款感觉不错的工具:
1、darts,darts的周期性检测工具比较方便,核心思想是通过自相关以及显著性检验来得到可靠的周期性检验结果,因为随着周期长度的增加,进行自相关系数计算的数据会越来越少,样本越小则相关系数计算的结果越不可靠,因此要引入显著性检验来检验相关系数计算结果的可靠性,初次之外,darts的经济学模型功能基本上sktime里有更好更统一的实现,darts的nn功能很鸡肋,感觉没有太大必要使用,darts目前只能支持单序列的问题,无法处理多序列问题,和skearn,xgb,lgb这些工具的统一性也很差;
2、sktime,个人感觉最好用的时间序列工具包,支持原生的pandas和numpy数据,和sklearn api的结合非常紧密,可以看作是sklearn在时间序列问题上的扩展,基本上除了nn之外,经济学模型和机器学习模型的全流程建模的设计都有,很方便地进行实验,并且其经济学模型功能和darts基本是一致的(常用的经济学模型也就那几个了。。);
3、nn部分,pytorch-forecasting,pytorch-forecasting设计的timeseriesdataset可以说是非常非常的便利了,针对多序列和单序列的数据转换,向量预测和seq2seq式迭代预测的数据构建都极其方便,并且内置了各种group 标准化,log变换等功能,因为torch和numpy本身的紧密度很高,将data loader得到的tensor直接转化为numpy就可以很方便的将构建完的数据集用于gbdt这类模型的建模了,比较推荐。
pytorch-forecasting除了timeseriesdataset和数据的一些预处理的功能之外,其它的功能就不推荐了,模型部分维护的并不好,不同的时间序列模型接口不统一,用起来非常混乱,实际上通过timeseriesdataset的方式构建标准的适合nn的数据形式之后,模型部分可以自己用torch lightning来写;
4、gluonts,大一统,目前还在看介绍,算法的种类基本上是整个git上最全的了,你了解的和你不了解的模型基本都实现了,并且也有和pandas,numpy结合紧密的时间序列数据格式,api相对统一的多,文档也比较丰富,美中不足的就是对于mxnet支持较好,对于torch也有支持(但是不知道支持到什么程度,目前看文档是可以支持模型构建,但是loss的计算等等不知道能不能也支持)。
所以最后的选型就是sktime和pytorch-forecasting的timeseriesdataset以及gluonts了。
pytorch-forecasting可以比较方便的测试新模型,数据处理完毕,只要把相应的模型的输入输出搞清楚直接forward就可以了,gluonts暂时研究的不深入,后续看完了再更新一下吧。