0%

时间序列的区间预测/概率预测

一般我们做时间序列预测都是做点预测(point forecasting),很少会去考虑区间预测(interval forecasting),或者概率预测(probabilistic forecasting),但实际上区间预测也是很重要的,具体来说有这三方面的作用:

  1. 刻画不确定性以应对风险,预测都是服务于决策,那么在决策时就必然要考虑到可能的风险,也就是最好的情况和最坏的情况,因此就需要使用区间预测来描述预测值可能的上下限
  2. 特定场景下的用处,比如供应链中的库存管理模型,使用区间预测/概率预测可以用来最优化补货量,如果需要满足95%的服务水平,那么就可以输出95%分位数下对应的销量预测值来作为补货量
  3. 好看,业务方和老板在看你预测结果时,如果只有一条干巴巴的曲线是不好说服他们的,毕竟预测就是个玄学,那就整一些花里胡哨的的,比如加个区间,这样他们看着就很开心了()

image.png
目前关于时间序列区间预测的方法似乎还没有一个系统性的总结,这里我就把自己调研看到的几种方法整理出来,根据我的分类,区间预测具体可以分为两类方法:

  1. 统计学方法,使用统计学上的一些方法来估计区间

  2. 损失函数法,通过定义特定的损失函数来输出区间

统计学方法

区间估计法

学过统计学的都会知道区间估计,要估计一个值的区间,首先会假设它服从正态分布,进一步再计算出这个值的估计标准差,然后给定某个置信度,比如95%,查表就可以得到Z值为1.96,那么就可以把Z值乘上标准差,再用均值加减一下,就可以得到区间的左端和右端。
区间预测也用到的同样的思路,但是在区间预测里,我们并不会假设预测值服从正态分布,而是假设误差服从正态分布,然后估计出误差的上下限,再把他加到预测值里面,就可以得到预测值的上下限了,具体来说,步骤如下:

  1. 假设预测误差服从均值为0的正态分布,估计预测误差的标准差

  2. 给定置信度,查表得到Z值

  3. 计算预测误差的上限和下限

  4. 将上下限加到预测值里面,得到一个预测区间

\(\hat{y}_{T+h \mid T} \pm k \hat{\sigma}_{h}\)
但是,怎么得到预测误差的标准差呢?很多传统统计学的预测方法都是直接用训练误差的标准差,也有了很多成熟的估计方法,但是由于训练数据上是过拟合的,会导致这个标准差比较小,就导致最后出来的预测区间也比较小,所以,比较合理的做法是在训练数据集上先划分出一个验证集,然后使用验证集上的预测误差来估计标准差。

Bootstrap

bootstrap,也就是自助采样法,这个方法的思路也是先估计出一个误差的上下限,然后把这个上下限加到原来的预测值中,进而得到预测区间,不过,bootstrap不需要假定误差服从正态分布,而是通过采用N次的预测误差,然后取这N次的误差的分位数作为上下限,比如抽样了三次误差,分别为[-50,0,50], 则5%分位数为-45,95%分位数为45,把这个分位数误差加到预测值上就得到了预测区间。
参考链接:https://otexts.com/fppcn/prediction-intervals.html

损失函数

最近几年,基于深度的时序预测方法也很多,所以也衍生出了一些区间预测的方法,但具体来说都是从损失函数层面来实现的。

分位数损失

分位数的损失函数形式如下所示:
\(L_{q}(y, \hat{y})=q(y-\hat{y})_{+}+(1-q)(\hat{y}-y)_{+}\)
其中,\((\cdot)_{+}=\max (0, \cdot)\).,加号左边那项代表的就是预测值小于真实值的loss,右边那项代表队是预测值大于真实值时的loss,我们通过取不同的q来理解下这个函数:

  • \(q=0.5\)时,两边的权重相等,这个损失函数就和MAE一样
  • \(q=0.95\)时,左边那项的loss权重比较大,因此,模型就会尽可能的使得预测值大于真实值,这样才能使得整体的loss小,这就起到了一个拉高预测值的作用,也可以理解为预测区间的上限
  • \(q=0.05\)时,这时候就是右边的那项loss权重比较大,因此,模型就会尽可能使得预测值小于真实值,才能保证整体的loss小,这就起到了一个拉低预测值的作用,也可以理解为预测区间的下限

在实操时,我们一般会指定三个分位数,如(0.1, 0.5, 0.9),把这三个分位数损失加起来作为最终的损失函数,在预测时就可以输出三个值,分别对应:10%的区间预测,点预测以及90%的区间预测,目前很多基于深度学习的时序预测算法都用到了这个损失函数,比如MQRNN/CNN, TFT等,GBDT也可以使用这个损失,像lightgbm和xgboost的objective里面也都有quantile这个选项,也都可以输出区间预测。

负对数似然损失

这个思路我最早是在DeepAR那看到的,大概思路是首先指定一个预测值服从的概率分布,如正态分布,然后,使用神经网络模型分别预测这个概率分布的参数,比如正态分布就是预测他的均值和方差,接着构造负对数似然函数作为损失函数,优化这个损失函数就可以到得到概率分布的参数,最后就可以得到预测时每一步的概率分布,知道了概率分布,那么就可以通过蒙特卡洛采样的方式来生成预测值和区间预测了,比如对这个概率分布采样100次,那这100次的均值就是点预测的结果,95%分位数和5%分位数就可以对应区间预测的结果。 # 开源工具包的实现

GluonTS

  1. 对于自回归模型,通过预测概率分布来实现概率预测

  2. 对于其他模型,使用分位数回归

Darts

  1. 对于传统统计学模型,使用区间估计法进行概率预测

  2. 对于部分深度学习模型,使用负对数似然损失

MAPIE

这是一个专门用来做区间预测的包,基于sklearn接口进行开发的,支持回归、分类、时序回归的区间预测,其中,时序部分的区间预测用了一篇论文(https://arxiv.org/abs/2010.09107)的算法,叫做EnbPI,号称是一个通用的distribution-free的时序区间预测框架,不需要划分验证集重新训练,原理太复杂没去看,试着跑了下demo有点慢,并且目前这个包只支持sklearn那边的模型。

总结

时间序列的区间预测方法按照我的分类方式大致可以分为两大类,其中,统计学方法通过估计误差的上下限再加到原来的预测值上面进行区间预测,一般在传统统计学模型(ARIMA、指数平滑法等)上应用很多,因为估计误差的方法已经有了非常成熟的公式,很多包也集成了这些区间预测,但应用在其他模型上面可能先需要划分训练集和验证集,估计出误差后再对测试集进行区间预测。

而损失函数的方法只能用在深度学习和GBDT这些靠优化损失函数来预测的模型,具体可以分为分位数损失和负对数似然损失,分位数损失通过损失函数拉高/拉低预测值来实现区间预测的效果,GBDT和深度学习都能用,而负对数似然损失通过直接预测概率分布,然后采样的方式来实现预测,只能用在深度学习模型上

参考

  1. Probabilistic Forecasting in Darts - Unit8

  2. Time Series Forecasting: Prediction Intervals | by Brendan Artley | Towards Data Science

  3. 3.5 预测区间 | 预测: 方法与实践

  4. [1906.05264] GluonTS: Probabilistic Time Series Models in Python

欢迎关注我的其它发布渠道