python | prophet的案例实践:趋势检验、突变点检验等

5年前prophet刚出来的时候试用过R版本的prophet:
R+python︱Facebook大规模时序预测『真』神器——Prophet(遍地代码图)

现在最近的一些研究涉及时序数据,所以回来再看看python版本的。



1 趋势检测

参考官方文档:Trend Changepoints
怎么训练出一个NB的Prophet模型

1.1 趋势检验案例

根据官方简单改编的:

import pandas as pd
from prophet import Prophet
from datetime import datetime
# 构造数据集
start = datetime(2017, 10, 1)
end = datetime(2018, 10, 1)
rng = pd.date_range(start, end, freq='W')
data = pd.Series(np.random.randn(len(rng)), index=rng)
data = data.reset_index()
data.columns = ['ds','y']

m = Prophet(changepoint_prior_scale=5,yearly_seasonality=False)
# 兼顾异常值,0.8,兼顾80%的异常值;越大兼顾的越多,波动性越大
# 越小越平滑
# Proportion of history in which trend changepoints will be estimated
m.fit(data)
forecast = m.predict(data)

# Python
from prophet.plot import add_changepoints_to_plot
fig = m.plot(forecast)
a = add_changepoints_to_plot(fig.gca(), m, forecast)

# 找到突变时间线
threshold = 0.01
signif_changepoints = m.changepoints[
    np.abs(np.nanmean(m.params['delta'], axis=0)) >= threshold
] if len(m.changepoints) > 0 else []
signif_changepoints

其中关于改变点有几个参数:

  • changepoints,
  • n_changepoints,
  • changepoint_range,
  • changepoint_prior_scale
    以上都是趋势性参数

1.2 Prophet模型的趋势参数

参数 描述
growth growth是指模型的趋势函数,目前取值有2种,linear和logistic
changepoints Changepoint是指一个特殊的日期,在这个日期,模型的趋势将发生改变。而changepoints是指潜在changepoint的所有日期,如果不指明则模型将自动识别。
n_changepoints 最大的Changepoint的数量。如果changepoints不为None,则本参数不生效。
changepoint_range 是指changepoint在历史数据中出现的时间范围,与n_changeponits配合使用,changepoint_range决定了changepoint能出现在离当前时间最近的时间点,changepont_range越大,changepoint可以出现的距离现在越近。当指定changepoints时,本参数不生效
changepoint_prior_scale 设定自动突变点选择的灵活性,值越大越容易出现changepoint

1.2.1 growth

growth是指模型的趋势函数,目前取值有2种,linear和logistic,分别如图1-1及图1-2所示。趋势会在changepoint处出现突变点。

此图为图1-1 linear趋势:
在这里插入图片描述

此图为图1-2 logistic趋势:

在这里插入图片描述
可不可能出现同一个模型既有linear趋势,又有logistic趋势,就像下面这样:
在这里插入图片描述
Prophet的趋势模型要么是linear要么是logistic。而上图之所以像是两种的叠加,是因为prophet的设计师为了让趋势函数可微(连续,就理解成连续吧)做了平滑处理,
在这里插入图片描述
上面就是论文中做平滑处理的公式。

1.2.2 Changepoints

hangeponits形状如[‘2013-01-01’,’2013-09-01’,’2017-02-5’],是changepoint的列表。

Changepoints是一个非常重要的参数,但用户在决定设置此值时必须要注意,这个参数设置之后模型将不会自动寻找changepoints(同时n_changepoints和changepoint_range均不会生效),这就意味着手动设置的changeponits必须准确且完整,否则福布湿不建议大家设置此项。

1.2.3 n_changeponits、changepoint_range

这2个参数是模型自动识别changepoint时需要的,n_changepoints限制了changepoint的最大数量,changepoint_range限制了changepoint在历史数据中出现的时间范围。
例如图1-1中changepoint_range福布湿设置的是0.5,而图1-3中设置的是0.8,如果把图1-3中的changepoint_range设置为0.2,那么所有的changpoint均只能出现在2020-01-01至2020-02-01的范围内。

1.3 Prophet模型的周期性参数

怎么训练出一个NB的Prophet模型

参数 描述
yearly_seasonality 年周期性,True为启用,false为关闭,如果设置为自然数n,则n代表傅里叶级数的项数,项数越多,模型将拟合的越好,但是也越容易过拟合,因此论文中推荐年周期性的项数取10,而周的(weekly_seasonality)取3。 一般来讲当历史数据大于1年时模型默认为True(项数默认为10),否则默认为False
weekly_seasonality 周周期性,True为启用,false为关闭,如果设置为自然数n,则n代表傅里叶级数的项数,项数越多,模型将拟合的越好,但是也越容易过拟合,因此论文中推荐取3。 一般来讲当历史数据大于1周时模型默认为True(项数默认为3),否则默认为False
daily_seasonality 天周期性,当时间序列为小时级别序列时才会开启。
seasonality_mode 季节模型方式,‘additive’(加法模型) (默认) 或者 ‘multiplicative’(乘法模型)
seasonality_prior_scale 改变周期性影响因素的强度,值越大,周期性因素在预测值中占比越大

周期性参数设置相对较为固化,除了seasonality_mode和seasonality_prior_scale可能需要手动调整外其余各项一般情况下保持为默认值即可(当然具体问题具体分析,傅里叶项数在某些特殊情况下也可能需要调整)。

傅里叶级数跟泰勒展开式一样,都是用特定的级数形式拟合某个函数,傅里叶级数是专门为周期性函数设计的,也就是说只要某个函数是周期函数就能使用傅里叶级数拟合。有兴趣的同学可以看下知乎上的这个文章:
傅里叶系列(一)傅里叶级数的推导

seasonality_mode的季节模型类型如果大家不深究按字面意思理解即可。

1.4 Prophet模型节假日参数

参数 描述
holidays 节假日或特殊日期,商业活动中活动日期是这类日期的典型代表
holiday_prior_scale 改变假日模型的强度

Holidays参数是一个pd.DataFrame:

holiday ds
元旦 2019/1/1
元旦 2018/1/1

holiday是特殊日期的时间,ds是时间(pd.Timestamp类型),upper_window和lower_window分别指特殊日期的影响上下限。

在Prophet中,认为holiday服从正态分布,正态分布的轴为ds。因此,prophet在预测节假日时会以正态分布作为来估计预测值,但这个过程只是一个先验估计的过程,如果模型后面发现这个holiday期间内不服从正态分布,那么模型将生硬的拟合该节假日。如图1-4中所示,大家可以自行体会。
在这里插入图片描述
holidays这个参数非常重要,对整个模型的影响极大,因此大家在构建这个参数时一定要给予相当的重视。

holidays在模型中是一个广义的概念,不仅指节假日,也指活动日期,特殊事件日期等,因此大家在设置holidays时一定要确保完整,同时对于upper_window和lower_window的设置也应符合实际情况。

值得注意的是holidays的数量应尽量少,过多的holidays会对模型的过拟合现象加重,如果holidays的数量超过了整体数据的30%,工程师就应该考虑是否去掉一些影响较小的节假日。

1.5 Prophet模型其他参数

参数 描述
mcmc_samples 概率估计方式。如果为0将会采用最大后验概率估计(MAP),如果为n(n>0)将会以n个马尔科夫采样样本做全贝叶斯推断。 估计有同学有疑问,这些个概率估计的东西跟本模型有毛关系?大家仔细看下图1-4中的蓝色曲线和淡蓝色区域,这其实就是预测结果,而采样估计就是用来给出淡蓝色区域的(uncertainty intervals),大家可以理解为置信区间或者是预测结果的上下限(虽然外国佬叫它‘不确定区间’)。 当mcmc_samples=0的时候,只有趋势因素会存在这种估计,当mcmc_samples>0时,周期性因素才会存在这种估计。
interval_width uncertainty intervals 的宽度,是一个浮点数,越大允许的uncertainty intervals范围越大
uncertainty_samples 用来估计uncertainty intervals的采样次数,如果设置为0或者False,就不会进行uncertainty intervals的估计,从而加快模型的训练速度。
stan_backend CMDSTANPY或者PYSTAN。一般PYSTAN在linux上使用,cmdstanpy在微软操作系统上使用。提示下在微软操作系统上使用的同学,最好不要开启马尔科夫采样(就是不要把mcmc_samples设成大于0),因为微软操作系统上马尔科夫采样非常慢。

2 prophet 与 LSTM的对比案例

来自文章:时间序列神器之争:Prophet VS LSTM

目前成熟的时间序列预测算法很多,但商业领域性能优越的却不多,经过多种尝试,给大家推荐2种时间序列算法:facebook开源的Prophet算法和LSTM深度学习算法。
现将个人理解的2种算法特性予以简要说明:

(1)、在训练时间上,prophet几十秒就能出结果,而lstm往往需要1个半小时,更是随着网络层数和特征数量的增加而增加。
(2)、Prophet是一个为商业预测而生的时间序列预测模型,因此在很多方便都有针对性的优化,而lstm的初衷是nlp。
(3)、Prophet无需特征处理即可使用,参数调优也明确简单。而lstm则需要先进行必要的特征处理,其次要进行正确的网络结构设计,因此lstm相对prophet更为复杂。
(4)、Lstm需要更多的数据进行学习,否则无法消除欠拟合的情形。而prophet不同,prophet基于统计学,有完整的数学理论支撑,因此更容易从少量的数据中完成学习。
(5)、传统的时间序列预测算法只支持单纬度,但LSTM能支持多纬度,也就是说LSTM能考虑促销活动,目标用户特性,产品特性等

Prophet的核心是调参,步骤如下:

  • 1、首先我们去除数据中的异常点(outlier),直接赋值为none就可以,因为Prophet的设计中可以通过插值处理缺失值,但是对异常值比较敏感。
  • 2、选择趋势模型,默认使用分段线性的趋势,但是如果认为模型的趋势是按照log函数方式增长的,可设置growth='logistic’从而使用分段log的增长方式
  • 3、 设置趋势转折点(changepoint),如果我们知道时间序列的趋势会在某些位置发现转变,可以进行人工设置,比如某一天有新产品上线会影响我们的走势,我们可以将这个时刻设置为转折点。如果自己不设置,算法会自己总结changepoint。
  • 4、 设置周期性,模型默认是带有年和星期以及天的周期性,其他月、小时的周期性需要自己根据数据的特征进行设置,或者设置将年和星期等周期关闭。
    设置节假日特征,如果我们的数据存在节假日的突增或者突降,我们可以设置holiday参数来进行调节,可以设置不同的holiday,例如五一一种,国庆一种,影响大小不一样,时间段也不一样。
  • 5、 此时可以简单的进行作图观察,然后可以根据经验继续调节上述模型参数,同时根据模型是否过拟合以及对什么成分过拟合,我们可以对应调节seasonality_prior_scale、holidays_prior_scale、changepoint_prior_scale参数。

9 参考文献

  • Prophet官方文档:https://facebook.github.io/prophet/
  • Prophet论文:https://peerj.com/preprints/3190/
  • Prophet-github:https://github.com/facebook/prophet

猜你喜欢

转载自blog.csdn.net/sinat_26917383/article/details/125557640
今日推荐