1. Prophet简介
Github:github.com/facebook/pro 官方网址:facebook.github.io/prop
2. Prophet算法原理
![](https://oss-emcsprod-public.modb.pro/wechatSpider/modb_20210412_63dbce2a-9b67-11eb-ae49-00163e068ecd.png)
表示趋势项,它表示时间序列在非周期上面的变化趋势;
表示周期项,或者称为季节项,一般来说是以周或者年为单位;
表示节假日项,表示在当天是否存在节假日;
表示误差项或者称为剩余项。Prophet 算法就是通过拟合这几项,然后最后把它们累加起来就得到了时间序列的预测值。
趋势项模型![](https://oss-emcsprod-public.modb.pro/wechatSpider/modb_20210412_642549ce-9b67-11eb-ae49-00163e068ecd.png)
![](https://oss-emcsprod-public.modb.pro/wechatSpider/modb_20210412_64f0c1b2-9b67-11eb-ae49-00163e068ecd.png)
![](https://oss-emcsprod-public.modb.pro/wechatSpider/modb_20210412_650f335e-9b67-11eb-ae49-00163e068ecd.png)
![](https://oss-emcsprod-public.modb.pro/wechatSpider/modb_20210412_654950de-9b67-11eb-ae49-00163e068ecd.png)
![](https://oss-emcsprod-public.modb.pro/wechatSpider/modb_20210412_656f31aa-9b67-11eb-ae49-00163e068ecd.png)
![](https://oss-emcsprod-public.modb.pro/wechatSpider/modb_20210412_658a6290-9b67-11eb-ae49-00163e068ecd.png)
![](https://oss-emcsprod-public.modb.pro/wechatSpider/modb_20210412_654950de-9b67-11eb-ae49-00163e068ecd.png)
![](https://oss-emcsprod-public.modb.pro/wechatSpider/modb_20210412_65d6daa8-9b67-11eb-ae49-00163e068ecd.png)
![](https://oss-emcsprod-public.modb.pro/wechatSpider/modb_20210412_65fc59b8-9b67-11eb-ae49-00163e068ecd.png)
![](https://oss-emcsprod-public.modb.pro/wechatSpider/modb_20210412_662164f6-9b67-11eb-ae49-00163e068ecd.png)
![](https://oss-emcsprod-public.modb.pro/wechatSpider/modb_20210412_664e68a2-9b67-11eb-ae49-00163e068ecd.png)
![](https://oss-emcsprod-public.modb.pro/wechatSpider/modb_20210412_666de13c-9b67-11eb-ae49-00163e068ecd.png)
![](https://oss-emcsprod-public.modb.pro/wechatSpider/modb_20210412_669a0be0-9b67-11eb-ae49-00163e068ecd.png)
![](https://oss-emcsprod-public.modb.pro/wechatSpider/modb_20210412_66b58096-9b67-11eb-ae49-00163e068ecd.png)
![](https://oss-emcsprod-public.modb.pro/wechatSpider/modb_20210412_66d31a98-9b67-11eb-ae49-00163e068ecd.png)
![](https://oss-emcsprod-public.modb.pro/wechatSpider/modb_20210412_66efd926-9b67-11eb-ae49-00163e068ecd.png)
![](https://oss-emcsprod-public.modb.pro/wechatSpider/modb_20210412_670f1fb6-9b67-11eb-ae49-00163e068ecd.png)
![](https://oss-emcsprod-public.modb.pro/wechatSpider/modb_20210412_673535ac-9b67-11eb-ae49-00163e068ecd.png)
![](https://oss-emcsprod-public.modb.pro/wechatSpider/modb_20210412_675300a0-9b67-11eb-ae49-00163e068ecd.png)
![](https://oss-emcsprod-public.modb.pro/wechatSpider/modb_20210412_676bf7f4-9b67-11eb-ae49-00163e068ecd.png)
![](https://oss-emcsprod-public.modb.pro/wechatSpider/modb_20210412_67a08bcc-9b67-11eb-ae49-00163e068ecd.png)
![](https://oss-emcsprod-public.modb.pro/wechatSpider/modb_20210412_67bb16ea-9b67-11eb-ae49-00163e068ecd.png)
![](https://oss-emcsprod-public.modb.pro/wechatSpider/modb_20210412_675300a0-9b67-11eb-ae49-00163e068ecd.png)
![](https://oss-emcsprod-public.modb.pro/wechatSpider/modb_20210412_6808273c-9b67-11eb-ae49-00163e068ecd.png)
![](https://oss-emcsprod-public.modb.pro/wechatSpider/modb_20210412_673535ac-9b67-11eb-ae49-00163e068ecd.png)
![](https://oss-emcsprod-public.modb.pro/wechatSpider/modb_20210412_68366bd8-9b67-11eb-ae49-00163e068ecd.png)
![](https://oss-emcsprod-public.modb.pro/wechatSpider/modb_20210412_6854d488-9b67-11eb-ae49-00163e068ecd.png)
![](https://oss-emcsprod-public.modb.pro/wechatSpider/modb_20210412_658a6290-9b67-11eb-ae49-00163e068ecd.png)
![](https://oss-emcsprod-public.modb.pro/wechatSpider/modb_20210412_65d6daa8-9b67-11eb-ae49-00163e068ecd.png)
![](https://oss-emcsprod-public.modb.pro/wechatSpider/modb_20210412_666de13c-9b67-11eb-ae49-00163e068ecd.png)
![](https://oss-emcsprod-public.modb.pro/wechatSpider/modb_20210412_68f8e55a-9b67-11eb-ae49-00163e068ecd.png)
季节项模型![](https://oss-emcsprod-public.modb.pro/wechatSpider/modb_20210412_645a0236-9b67-11eb-ae49-00163e068ecd.png)
周期性的变化因子是时间序列预测模型都会考虑的因素,为了拟合并预测季节的效果,Prophet基于傅里叶级数提出了一个灵活的模型。季节效应S(t)根据以下方程进行估算: 表示时间序列的周期,
表示以年为周期,
表示以周为周期。季节效应S(t)傅立叶级数形式是:
对季节性建模时,需要在给定N的情况下,估计参数傅里叶阶数N是一个重要的参数,它用来定义模型中是否考虑高频变化。对时间序列来说,如果分析师认为高频变化的成分只是噪声,没必要在模型中考虑,可以把N设为较低的值。如果不是,N可以被设置为较高的值并用于提升预测精度。就作者的经验而言,对于以年为周期的序列
而言,
;对于以周为周期的序列
而言,
。
当 时,
当 时,
因此,时间序列的季节项就是: 而
。这里的
值越大,表示季节的效应越明显;这个值越小,表示季节的效应越不明显。同时,在代码里面,seasonality_mode 也对应着两种模式,分别是加法和乘法,默认是加法的形式。
节假日项模型![](https://oss-emcsprod-public.modb.pro/wechatSpider/modb_20210412_648048b0-9b67-11eb-ae49-00163e068ecd.png)
现实生活中的预测场景中有很多节假日,而且不同的国家有着不同的假期。还有类似于618、双十一等这样不列入官方节日,但是对于指标预测影响非常重要的日期。在 Prophet 里面,通过维基百科里面对各个国家的节假日的描述,hdays.py 收集了各个国家的特殊节假日。Prophet还允许分析师使用过去和未来事件的自定义列表,例如印度的The Super Bowl,国内的双十一等。
由于每个节假日对时间序列的影响程度不一样,例如春节,国庆节则是七天的假期,对于劳动节等假期来说则假日较短。因此,不同的节假日可以看成相互独立的模型,并且可以为不同的节假日设置不同的前后窗口值,表示该节假日会影响前后一段时间的时间序列。用数学语言来说,对与第 个节假日来说,
表示该节假日的前后一段时间。为了表示节假日效应,我们需要一个相应的indicator函数,同时需要一个参数
来表示节假日的影响范围。假设我们有
个节假日,那么
其中
其中 该正态分布的标准差默认值是 10,当值越大时,表示节假日对模型的影响越大;当值越小时,表示节假日对模型的效果越小。用户可以根据自己的情况自行调整。
模型拟合
结合上面对增长项,季节项,节假日项三方面的详细讲解,现在可以用线性将三块结合一起来拟合时间序列:
在 Prophet 中,可以使用 Prophet 默认的参数,也可以自己设置以下四种参数:
Capacity:在增量函数是逻辑回归函数的时候,需要设置的容量值。
Change Points:可以通过 n_changepoints 和 changepoint_range 来进行等距的变点设置,也可以通过人工设置的方式来指定时间序列的变点。
季节性和节假日:可以根据实际的业务需求来指定相应的节假日。
光滑参数:
changepoint_prior_scale 可以用来控制趋势的灵活度,
seasonality_prior_scale 用来控制季节项的灵活度,
holidays prior scale 用来控制节假日的灵活度。
1. 趋势参数
参数 | 描述 |
growth | ‘linear’或‘logistic’规定线性或逻辑趋势 |
changepoints | 包括潜在突变点的日期列表(默认为自动识别) |
n_changepoints | 若不指定突变点,需要提供自动识别的突变点数 |
changepoint_prior_scale | 设定自动突变点选择的灵活性 |
参数 | 描述 |
yearly_seasonality | 周期为年的季节性 |
weekly_seasonality | 周期为周的季节性 |
daily_seasonality | 周期为日的季节性 |
holidays | 内置的节假日名称和日期 |
seasonality_prior_scale | 改变季节模型的强度 |
holiday_prior_scale | 改变假日模型的强度 |
3. Prophet实战(附Python代码)
数据链接:https://datahack.analyticsvidhya.com/contest/practice-problem-time-series-2/
#import data
import pandas as pd
import numpy as np
from fbprophet import Prophet
#Read train and test
train = pd.read_csv('Train_SU63ISt.csv')
test = pd.read_csv('Test_0qrQsBZ.csv')
#Convert to datetime format
train['Datetime'] = pd.to_datetime(train.Datetime,format='%d-%m-%Y %H:%M')
test['Datetime'] = pd.to_datetime(test.Datetime,format='%d-%m-%Y %H:%M')
train['hour'] = train.Datetime.dt.hour
我们可以看到时间序列中有很多噪声。我们可以对其进行重采样并汇总,得到一个噪声更少的新序列,进而更易建模。
# Calculate average hourly fraction
hourly_frac = train.groupby(['hour']).mean()/np.sum(train.groupby(['hour']).mean())
hourly_frac.drop(['ID'], axis = 1, inplace = True)
hourly_frac.columns = ['fraction']
# convert to time series from dataframe
train.index = train.Datetime
train.drop(['ID','hour','Datetime'], axis = 1, inplace = True)
daily_train = train.resample('D').sum()
Prophet要求时间序列中的变量名为:
y -> 目标(Target)
ds -> 时间(Datetime)
因此,下一步是基于上述规范来转换数据文件:
daily_train['ds'] = daily_train.index
daily_train['y'] = daily_train.Count
daily_train.drop(['Count'],axis = 1, inplace = True)
拟合Prophet模型(未设置的参数表明默认原设置):
#参数设置
m = Prophet(yearly_seasonality = True, seasonality_prior_scale=0.1)
#模型拟合
m.fit(daily_train)
#预测窗口
future = m.make_future_dataframe(periods=213)
#模型预测
forecast = m.predict(future)
#预测结果可视化
fig = m.plot(forecast)
我们可以通过以下命令来查看各个成分:
m.plot_components(forecast)
基于每日数据的预测如下。
![](https://oss-emcsprod-public.modb.pro/wechatSpider/modb_20210412_6ca65b7e-9b67-11eb-ae49-00163e068ecd.png)
![](https://oss-emcsprod-public.modb.pro/wechatSpider/modb_20210412_6cbf0570-9b67-11eb-ae49-00163e068ecd.png)