腾讯技术工程 | 基于Prophet的时间序列预测

预测将来永远是一件让人兴奋而又神奇的事。为此,人们研究了许多时间序列预测模型。然而,大部分的时间序列模型都由于预测的问题过于复杂而效果不理想。这是由于时间序列预测不光须要大量的统计知识,更重要的是它须要将问题的背景知识融入其中为此,Prophet充分的将二者融合了起来提供了一种更简单、灵活的预测方式,而且在预测准确率上达到了与专业分析师相媲美的程度。若是你还在为时间序列预测而苦恼,那就一块儿走进奋而又神奇的Prophet世界吧。html


前言
json



时间序列预测一直是预测问题中的难点,人们很难找到一个适用场景丰富的通用模型,这是由于现实中每一个预测问题的背景知识,例如数据的产生过程,每每是不一样的,即便是同一类问题,影响这些预测值的因素与程度也每每不一样,再加上预测问题每每须要大量专业的统计知识,这又给分析人员带来了难度,这些都使得时间序列预测问题变得尤为复杂。框架

传统的时间序列预测方法,例如ARIMA(autoregressive integrated moving average)模型,在R与Python中都有实现。虽然这些传统方法已经用在不少场景中了,但它们一般有以下缺陷:ide

a.适用的时序数据过于局限
例如最通用的ARIMA模型,其要求时序数据是稳定的,或者经过差分化后是稳定的,且在差分运算时提取的是固定周期的信息。这每每很难符合现实数据的状况。函数

b.缺失值须要填补
对于数据中存在缺失值的状况,传统的方法都须要先进行缺失值填补,这很大程度上损害了数据的可靠性。lua

c.模型缺少灵活性
传统模型仅在于构建数据中的临时依赖关系,这种模型过于不够灵活,很难让使用者引入问题的背景知识,或者一些有用的假设。spa

d.指导做用较弱
当前,虽然R与Python中实现了这些方法并提供了可视化效果,下降了模型的使用门槛。但因为模型自己的缘由,这些展示的结果也很难让使用者更清楚地分析影响预测准确率的潜在缘由。code


总之,传统的时间序列预测在模型的准确率以及与使用者之间的互动上很难达到理想的融合。orm

近期,facebook发布了prophet(“先知”)项目,它以更简单、灵活的预测方式以及可以得到与经验丰富的分析师相媲美的预测结果引发了人们的普遍关注。下面咱们介绍一下Prophet。htm


Prophet介绍


2.1总体框架

1.jpg

上图是prophet的总体框架,整个过程分为四部分:Modeling、Forecast Evaluation、Surface Problems以及Visually Inspect Forecasts。从总体上看,这是一个循环结构,而这个结构又能够根据虚线分为分析师操纵部分与自动化部分,所以,整个过程就是分析师与自动化过程相结合的循环体系,也是一种将问题背景知识与统计分析融合起来的过程,这种结合大大的增长了模型的适用范围,提升了模型的准确性。按照上述的四个部分,prophet的预测过程为:

a.Modeling:创建时间序列模型。分析师根据预测问题的背景选择一个合适的模型。


b.Forecast Evaluation:模型评估。根据模型对历史数据进行仿真,在模型的参数不肯定的状况下,咱们能够进行多种尝试,并根据对应的仿真效果评估哪一种模型更适合。


c.Surface Problems:呈现问题。若是尝试了多种参数后,模型的总体表现依然不理想,这个时候能够将偏差较大的潜在缘由呈现给分析师。


d.Visually Inspect Forecasts:以可视化的方式反馈整个预测结果。当问题反馈给分析师后,分析师考虑是否进一步调整和构建模型。

2.2适用场景

前文提到,不一样时间序列预测问题的解决方案也各有不用。Prophet适用于有以下特征的业务问题:

a.有至少几个月(最好是一年)的每小时、天天或每周观察的历史数据;


b.有多种人类规模级别的较强的季节性趋势:每周的一些天和每一年的一些时间;


c.有事先知道的以不按期的间隔发生的重要节假日(好比国庆节);


d.缺失的历史数据或较大的异常数据的数量在合理范围内;


e.有历史趋势的变化(好比由于产品发布);


f.对于数据中蕴含的非线性增加的趋势都有一个天然极限或饱和状态。

2.3 模型原理

模型的总体构建以下:

00.jpg

模型(1)总体由三部分组成:growth(增加趋势)、seasonality(季节趋势)以及holidays(节假日对预测值的影响)。其中g(t)表示增加函数,用来拟合时间序列中预测值的非周期性变化;s(t)用来表示周期性变化,好比说每周,每一年中的季节等;h(t)表示时间序列中那些潜在的具备非固定周期的节假日对预测值形成的影响。最后0.jpg为噪声项,表示模型未预测到的波动,这里假设0.jpg是高斯分布的。


能够看出这是一种相似generalized additive model(GAM)的模型,不一样于以往的时间序列预测模型(例如ARIMA),上述的模型将预测问题视做曲线拟合问题。这样作具备不少实践价值:


a.灵活度高,许多具备不一样周期以及不一样假设的季节性趋势能很容易的被引入;


b.时间序列中无需有一个固定的周期,也不须要在拟合前对缺失值进行填补,这是传统的(例如ARIMA)模型所办不到的;


c.拟合很是快,容许分析师交互式的探索模型的效果;


d.模型中参数的解释性很强,可让分析师根据启发来加强某部分假设。


下面分别介绍模型中各部分的构建。


2.3.1 增加趋势

增加趋势是整个模型的核心组件,它表示认为整个时间序列是如何增加的,以及预期将来时间里是如何增加的。这部分为分析师提供了两种模型:Non-linear growth(非线性增加)和Linear growth(线性增加)。


1.Non-linear growth

非线性增加的公式采用了逻辑回归的模型:

2.jpg

这里,C是承载量,它限定了所能增加的最大值,k表示增加率,b为偏移量。
固然,实际的增加模型远没有这么简单,Prophet主要考虑了两个现实问题:


(1)C值并不必定是常数;(2)增加率也不必定是一沉不变的。对于(1),将C构建成随时间变化的函数:C(t) = K 或者 C(t) = Mt + K。下面详细论述。


(2)的解决:首先模型定义了增加率k发生变化时对应的点,咱们将其称做changepoints,用0000.png表示,这些点对应的斜率调整值用表示,全部的斜率调整值造成一个向量000.png。此时,每一个changepoint点对应的增加率就变为3.jpg。若是有以下定义:

111.jpg

则t时刻的增加率就能够表示为:99.jpg


当增加率k调整后,每一个changepoint点对应的偏移量b也应该相应调整以链接每一个分段的最后一个时间点,表达式以下:

4.jpg

综上,结合(1)和(2),最终的分段式逻辑回归增加模型为:

5.jpg


2.Linear growth

若是认为时间序列的总体增加趋势是线性的,那么就能够采用线性模型:

6.jpg

这里的参数定义与非线性增加同样,惟一不一样的是每一个changepoint对应的

44.jpg结合上述两种增加模型,咱们能够看到,对于增加趋势的预测,最重要的就是对这些changepoint的指定。使用时,既能够手动指定这些changepoint,也能够根据公式(3)和(4)自动识别。此时,认为

33.jpg其中22.jpg控制着模型总体的平滑程度。


2.3.2 季节性趋势

因为时间序列中有可能包含多种周期类型的季节性趋势,所以,傅里叶级数能够用来近似表达这个周期属性,公式以下:

8.jpg

其中,P表示某个固定的周期(例如用”天”作单位统计的数据中,年数据的P = 365.25,周数据的P = 7)。2N表示咱们但愿在模型中使用的这种周期的个数,较大的N值能够拟合出更复杂的季节性函数,然而也会带来更多的过拟合问题。按照经验值,年周期的N取10,周周期的N取3。


当将s(t)中的全部季节性时间序列模型组合成一个向量X(t),那么最终的季节性模型为:

9.jpg

其中,10.jpg,以此提升季节性模型的平滑性。


2.3.3 节假日模型

不少实际经验告诉咱们,节假日或者是一些大事件都会对时间序列形成很大影响,并且这些时间点每每不存在周期性。对这些点的分析是极其必要的,甚至有时候它的重要度远远超过了日常点。

鉴于每一个节假日(或者某个已知的大事件)的日期与影响程度存在差别,节假日模型将不一样节假日在不一样时间点下的影响视做独立的模型。同时为每一个模型设置了时间窗口,这主要是考虑到节假日的影响有窗口期(例如中秋节的前几天与后几天),模型将同一个窗口期中的影响设置为相同的值。例如,i表示节假日47.png表示窗口期中包含的时间t,则节假日模型h(t)可表示为:

11.jpg

其中,34.jpg表示窗口期中的节假日对预测值的影响。同季节性趋势的模型,这里能够定义:

12.jpg

那么

13.jpg

其中

14.jpg


Prophet的使用


3.1参数使用

下面是这个模块的参数解释,使用者可充分利用这些参数调整模型:

a.增加趋势的模型参数

growth:增加趋势模型。整个预测模型的核心组件,分为两种:”linear”与”logistic”,分别表明线性与非线性的增加,默认值:”linear”。


cap:承载量。非线性增加趋势中限定的最大值,预测值将在该点达到饱和。当选择非线性增加时,该项值必须给出。


changepoints(growth模型中的):改变点。使用者能够自主填写已知时刻的标示着增加率发生改变的”改变点”,若是不填则系统自动识别。默认值:“None”。


n_changepoints:用户指定潜在的”changepoint”的个数,默认值:25。


changepoint_prior_scale(growth模型中的):增加趋势模型的灵活度。调节”changepoint”选择的灵活度,值越大,选择的”changepoint”越多,从而使模型对历史数据的拟合程度变强,然而也增长了过拟合的风险。默认值:0.05。


b.季节趋势的模型参数

seasonality_prior_scale(seasonality模型中的):调节季节性组件的强度。值越大,模型将适应更强的季节性波动,值越小,越抑制季节性波动,默认值:10.0。


c.节假日的模型参数

holidays_prior_scale(holidays模型中的):调节节假日模型组件的强度。值越大,该节假日对模型的影响越大,值越小,节假日的影响越小,默认值:10.0。


holidays:节假日的定义,设置节假日的json格式的配置文件,例如:

15.jpg

其中”holiday”表示某类节假日的名称,”ds”指定具体的节假日期,”lower_window”表示该节假日包括指定日期以前的多少天,”upper_window”表示该节假日包括指定日期以后的多少天,上述四个参数均须要配置。

d.预测中须要的其余参数

freq:数据中时间的统计单位(频率),默认为”D”,按天统计,具体可参考这里


periods:须要预测的将来时间的个数。例如按天统计的数据,想要预测将来一年时间内的状况,则需填写365。


mcmc_samples:mcmc采样,用于得到预测将来的不肯定性。若大于0,将作mcmc样本的全贝叶斯推理,若是为0,将作最大后验估计,默认值:0。


interval_width:衡量将来时间内趋势改变的程度。表示预测将来时使用的趋势间隔出现的频率和幅度与历史数据的类似度,值越大越类似,默认值:0.80。当mcmc_samples = 0时,该参数仅用于增加趋势模型的改变程度,当mcmc_samples > 0时,该参数也包括了季节性趋势改变的程度。


uncertainty_samples:用于估计将来时间的增加趋势间隔的仿真绘制数,默认值:1000。

3.2 结果读取与分析

完成以上的配置后,接下来就能够直接运行模型并得到结果了。

3.2.1 可视化结果

总体预测状况是咱们衡量模型总体预测效果的一个最直接的方式,它是咱们评估当前模型的预测水平的重要来源。同时可视化的展现能够帮助咱们有效分析预测结果中各个时间阶段的预测效果。


16.jpg

上图是一个总体的预测结果图,它包含了从历史数据的时间起点到指望预测的将来时间终点的结果。图中的ds坐标表示时间,y坐标对应预测值。图中的黑点表示已知的历史数据,由图上咱们很容易发现数据中的异常点,蓝色曲线表示模型的预测值。仔细查看蓝色曲线,咱们能够发现,曲线轮廓的上下边界有浅蓝色区域,它表示模型预测值的上、下边界。在评估结果时,咱们将蓝色曲线的预测值视做主预测值,上、下边界的预测值做为参考。除此以外,浅蓝色区域还能够很好的用于模型评估,例如对于下面这个图:


17.jpg


在2016年以后的模型预测部分,浅蓝色区域就过于宽泛,模型预测的上、下边界被逐渐放大不少倍。这说明模型的平滑性过大,致使异常点对结果形成了很大影响。所以,该模型不够合理,须要使用者从新设置参数或者对历史数据中的异常点进行预处理。


上述图是growth选择”linear”时的结果,若是认为时间序列呈非线性增加趋势,咱们用以下的图例来讲明:


18.jpg


体上与线性增加的结果表达没有太大差别,惟一须要注意的是,上图中的水平虚线表示了非线性增加趋势的承载量cap,预测结果将在该虚线处达到饱和。


除了上述的总体预测状况外,Prophet还提供了组成成分分析(简称成分分析),所谓成分分析就是指对公式(1)中的三大部分模型单独进行分析,成分分析有助于咱们考察模型中的各个组件分别对预测结果的影响,经过可视化的展现,咱们能够准确判断影响预测效果的具体缘由,从而针对性的解决。成分分析是咱们提升模型准确性的重要来源。例以下图结果:


19.jpg


上述四个图从上至下依次是对增加趋势模型(trend)、节假日模型(holidays)以及季节性模型(weekly和yearly)的展现。须要注意的是,若是没有在holidays参数里注明具体的节假日信息,模块也不会自动对这一部分进行分析。若是对于上面的结果你以为有不合理的地方,那么能够根据2.1中参数使用说明更改相应的成分影响,这里应该尽量的利用你的专业背景知识,以使各部分组成的影响更符合实际。举个例子,若是在每一年趋势”yearly”中你认为当前的效果过拟合了,那么就能够调解seasonality_prior_scale这个参数,值越小,这里的季节性波动就越小。


对于上面的可视化分析,这里总结几点建议,方便你们定位预测中的问题:

a.若是预测结果的偏差很大,考虑选取的模型是否准确,尝试调整增加率模型(growth)的参数,在必要的状况下也须要调整季节性(seasonality)参数。


b.若是在尝试的大多数方法中,某些日期的预测依然存在很大的偏差,这就说明历史数据中存在异常值。最好的办法就是找到这些异常值并剔除掉。使用者无需像其余方法那样对剔除的数据进行插值拟合,能够仅保留异常值对应的时间, 并将异常值修改成空值(NA),模型在预测时依然能够给出这个时间点对应的预测结果。


c.若是对历史数据进行仿真预测时发现,从一个截点到下一个截点偏差急剧的增长,这说明在两个截点期间数据的产生过程发生了较大的变化,此时两个截点之间应该增长一个”changepoint”,来对这期间的不一样阶段分别建模。


参考文献

Sean J. Taylor and Benjamin Letham.Forecasting at Scale.https://research.fb.com/prophet-forecasting-at-scale



1.png

相关文章
相关标签/搜索