1.思想
在时间序列分析领域,有一种常见的分析方法叫做时间序列的分解(Decomposition of Time Series),它把时间序列 分成几个部分,分别是季节项 ,趋势项 ,剩余项 。也就是说对所有的 ,都有
y t = S t + T t + R t y_{t}=S_{t}+T_{t}+R_{t} yt=St+Tt+Rt
除了加法的形式,还有乘法的形式,也就是:
y t = S t × T t × R t y_{t}=S_{t} \times T_{t} \times R_{t} yt=St×Tt×Rt
一般来说,在实际生活和生产环节中,除了季节项,趋势项,剩余项之外,通常还有节假日的效应。所以,在 prophet 算法里面,作者同时考虑了以上四项,也就是:
y ( t ) = g ( t ) + s ( t ) + h ( t ) + ϵ t y(t)=g(t)+s(t)+h(t)+\epsilon_{t} y(t)=g(t)+s(t)+h(t)+ϵt
其中 g ( t ) g(t) g(t)表示趋势项,它表示时间序列在非周期上面的变化趋势;
s ( t ) s(t) s(t)表示周期项,或者称为季节项,一般来说是以周或者年为单位;
h ( t ) h(t) h(t)表示节假日项,表示在当天是否存在节假日;
ϵ ( t ) \epsilon(t) ϵ(t)表示误差项或者称为剩余项。
Prophet 算法就是通过拟合这几项,然后最后把它们累加起来就得到了时间序列的预测值。
趋势项模型 g ( t ) g(t) g(t)
在 Prophet 算法里面,趋势项有两个重要的函数,一个是基于逻辑回归函数(logistic function)的,另一个是基于分段线性函数(piecewise linear function)的。
f ( x ) = C / ( 1 + e − k ( x − m ) ) f(x)=C /\left(1+e^{-k(x-m)}\right) f(x)=C/(1+e−k(x−m))
所以,分段的逻辑回归增长模型就是:
g ( t ) = C ( t ) 1 + exp ( − ( k + a ( t ) t δ ) ⋅ ( t − ( m + a ( t ) T γ ) g(t)=\frac{C(t)}{1+\exp \left(-\left(k+\boldsymbol{a}(t)^{t} \boldsymbol{\delta}\right) \cdot\left(t-\left(m+\boldsymbol{a}(t)^{T} \boldsymbol{\gamma}\right)\right.\right.} g(t)=1+exp(−(k+a(t)tδ)⋅(t−(m+a(t)Tγ)C(t)
基于分段线性函数的趋势项是怎么做的。众所周知,线性函数指的是 y = k x + b y=k x+b y=kx+b, 而分段线性函数指的是在每一个子区间上,函数都是线性函数,但是在整段区间上,函数并不完全是线性的。正如下图所示,分段线性函数就是一个折线的形状。
因此,基于分段线性函数的模型形如:
g ( t ) = ( k + a ( t ) δ ) ⋅ t + ( m + a ( t ) T γ ) g(t)=(k+\boldsymbol{a}(t) \boldsymbol{\delta}) \cdot t+\left(m+\boldsymbol{a}(t)^{T} \boldsymbol{\gamma}\right) g(t)=(k+a(t)δ)⋅t+(m+a(t)Tγ)
季节性趋势
时间序列通常会随着天,周,月,年等季节性的变化而呈现季节性的变化,也称为周期性的变化。对于周期函数而言,大家能够马上联想到的就是正弦余弦函数。而在数学分析中,区间内的周期性函数是可以通过正弦和余弦的函数来表示的:
在论文中,作者使用傅立叶级数来模拟时间序列的周期性。
时间序列的季节项就是:
节假日效应(holidays and events)
同时需要一个参数来表示节假日的影响范围。假设我们有L 个节假日,那么
Prophet 中可以设置的参数
在 Prophet 中,用户一般可以设置以下四种参数:
Capacity:在增量函数是逻辑回归函数的时候,需要设置的容量值。
Change Points:可以通过 n_changepoints 和 changepoint_range 来进行等距的变点设置,也可以通过人工设置的方式来指定时间序列的变点。
季节性和节假日:可以根据实际的业务需求来指定相应的节假日。
光滑参数: τ = \tau= τ= changepoint prior scale可以用来控制趋势的灵活度, σ = \sigma= σ=seasonality_prior_scale 用来控制季节项的灵活度, v = v= v= holidays prior scale 用来控制节假日的灵活度。
2、实践
初始化模型:m = Prophet()
拟合模型:m.fit(df)
计算预测值:periods 表示需要预测的点数,freq 表示时间序列的频率。
future = m.make_future_dataframe(periods=30, freq='min')
future.tail()
forecast = m.predict(future)画出预测图:
m.plot(forecast)
画出时间序列的分量:
m.plot_components(forecast)
参考:
- Forecasting at Scale;
- github prophet;
- FACEBOOK 时间序列预测算法 PROPHET 的研究;
- zhihu Prophet;