mac版的fbprophet从安装到使用手册

这篇是学习和使用笔记,参考内容比较多,没有很多原创,目的是希望大家快速入手这个包。
fbprophet这个包是facebook开源的时间序列预测包,因为其优良的性能,现在得到了大家的追捧,但是安装过程实在太多坑。

0.安装

本人使用mac电脑,因为这个包用到c++的环境,笔者是死活安装不成功,然后百度了好多问题无果,最终的解决方案是下面的安装步骤。

conda install pystan
#将安装很多依赖,不要用pip装,一定用conda装,嫌安装慢的,可以配置一个国内的镜像安装源。
#下载最新的prophet包,然后用
pip install fbprophet-0.6.tar.gz

期间如果遇到什么问题,欢迎随时私信我,这两步是最重要的。

1.入门

fbprophet完全继承了sklearn的模式,用fit,predict就可以进行使用。
fbprophet的输入是一个df,一般只包含两列第一列是日期,当然也可以是小时级别的,第二列就是具体的数据,这个包的好处显而易见,你不用去对数据特征进行处理了。
使用流程是:导包—导数据—建立一个prophet实例—fit—predict

import pandas as pd
from fbprophet import Prophet
sj = pd.read_excel('/Users/elliot/Desktop/manning.xlsx')
#sj.head(10)
m = Prophet()
m.fit(sj)#去训练
future = m.make_future_dataframe(periods=365)#再现有数据的基础上外推365天
future.tail()
pout = m.predict(future)#去预测
m.plot_components(pout)#画出分解图

2.饱和增长模型

饱和增长是指在资源有限的情况下事物的增长有上限的一种模式,符合大部分事物的发展规律,比如一个港口的吞吐量是不可能无限增长的,因为这个增长特征符合逻辑回归的曲线形式,因此又被成为logsitic模型,业内通常翻译为阻滞增长模型。
使用饱和增长模型,要在原有df的基础上新增一列cap,还要指定预测模型为logstic。

#前边导包导数据都一样的
sj['cap'] = 15.0
m = Prophet(growth='logistic')
m.fit(sj)
future = m.make_future_dataframe(periods=365)
future['cap'] = 15.0
future.tail()
pout = m.predict(future)
fig = m.plot(pout)

当然可以设置饱和增长的最大值,也可以设置饱和下降的最小值,看你业务需要,去调整变量名就好了。

3.突变点处理

当然了,时间序列不可能是完全平稳的,正常数据肯定存在突变点的,关于突变点检测有很多方法,网上基本都是现成的,比如用统计学的方法,用zscore,用孤立森林方法或者用其他方法。fbprophet可以自动识别突变点,这一点做得是比较好的。
这里我不想说的太复杂,简单说就是:同过changepoint和n_changepoint来指定异常点,如果啥也不给定,模型将从输入数据的前80%中找出25个异常点,怎么找呢,其实就是用了拐点检测的算法,具体不用搞懂。如果指定了就用你指定的日期作为异常点。
prophet对异常点的处理方法嘛很暴力就是忽略,相当于L1正则化,回想一下L1正则化就是将默写指标的权重设置为0来防止过拟合嘛。

from fbprophet.plot import add_changepoints_to_plot
fig = m.plot(pout)
a = add_changepoints_to_plot(fig.gca(), m, pout)

图如下所示:


异常点自动检测

如果你不想从80%数据找异常点咋办,设置changepoint_range这个参数,设置为0.9。
如果你想调整预测结果的灵活性,你可以设置changepoint_prior_scale这个参数,默认是0.05,放大会使预测结果范围更加宽广。

m = Prophet(changepoint_prior_scale=0.5)
m.fit(sj)
future = m.make_future_dataframe(periods=365)
forecast = m.predict(future)
fig = m.plot(forecast)
调整changepoint_prior_scale参数结果

4.节假日效应

节假日是影响数据波动的一个重要因素,比如双十一可以显著提高销量,春节期间则能显著降低物流量等。所以需要对节假日进行一个特殊处理。
要想分析节假日效应的话需要新增加一个dataframe,包含节假期和日期两个字段,预测数据中也要注明节假期。当然如果节假日是一个区间,你可以再dataframe中新增两列,lower_window 和 upper_window,将节假日扩展为一个区间。
建好节假日的dataframe后,建模的时候传参进去就可以了,没啥好说的。

playoffs = pd.DataFrame({
  'holiday': 'playoff',
  'ds': pd.to_datetime(['2008-01-13', '2009-01-03', '2010-01-16',
                        '2010-01-24', '2010-02-07', '2011-01-08',
                        '2013-01-12', '2014-01-12', '2014-01-19',
                        '2014-02-02', '2015-01-11', '2016-01-17',
                        '2016-01-24', '2016-02-07']),
  'lower_window': 0,
  'upper_window': 1,
})
superbowls = pd.DataFrame({
  'holiday': 'superbowl',
  'ds': pd.to_datetime(['2010-02-07', '2014-02-02', '2016-02-07']),
  'lower_window': 0,
  'upper_window': 1,
})
holidays = pd.concat((playoffs, superbowls))
m = Prophet(holidays=holidays)
m.fit(sj)
future = m.make_future_dataframe(periods=365)
forecast = m.predict(future)
fig = m.plot(forecast)
forecast[(forecast['playoff'] + forecast['superbowl']).abs() > 0][
        ['ds', 'playoff', 'superbowl']][-10:]
fig = m.plot_components(forecast)
from fbprophet.plot import plot_forecast_component
m.plot_forecast_component(forecast, 'superbowl')
#单独画出节假日影响的图像

如果发现节假日被过拟合了,你可以设置holidays_prior_scale参数来降低节假日的影响,这个参数默认取10,越大节假日影响越大,越小节假日影响越小。

5.季节性趋势

5.1 加法季节性

季节性使用傅里叶级数的方法进行建模的,这也是为什么fbprophet依赖C++包的原因。
在fbprophet中通过yearly_seasonality来调整,默认是10,如果季节性变化更明显,可以将这个数值调整的大一些,比如20。
你也可以通过指定weekly_seasonality和daily_seasonality两个参数来指定是否增加周和日的季节性。当然也可以通过add_seasality添加月、周、日甚至小时级别的季节性,三个参数,period、fourier_order,即傅里叶级数和prior_scale,先验规模,用来判断过拟合的。

m = Prophet(weekly_seasonality=False)
m.add_seasonality(name='monthly', period=30.5, fourier_order=5,prior_scale=0.1)
forecast = m.fit(sj).predict(future)
fig = m.plot_components(forecast)

同节假日相同,如果发现季节被过拟合了,可以设置 seasonality_prior_scale来调整。

5.2 乘法季节性

有些时候采用加法季节性是无效的,比如航空数据,有明显的随年度增加的趋势,但季节变化趋势也随着年份的增加发生了改变,采用传统的加法模型就不可行了。这时候可以尝试采用乘法季节性模型,就是在建模时候增加seasonality_mode='multiplicative'参数。值得注意的是因为设置了乘法模型,所以季节性和节假日都是乘法的关系。

m = Prophet(seasonality_mode='multiplicative')
m.fit(df)
forecast = m.predict(future)
fig = m.plot(forecast)
fig = m.plot_components(forecast)

当然了你也可以设置加法或者乘法,比如上述代码设置了季节性为乘法,那么你新增加一个季节性的时候可以指定是乘法或加法,这种做法就比较灵活。

m = Prophet(seasonality_mode='multiplicative')
m.add_seasonality('quarterly', period=91.25, fourier_order=8, mode='additive')

6.附加回归量

附加回归量是说有的因素可能影响预测结果,但是这个影响由没有展现出明显的年/月/日周期性,这时候可以加一个附加的回归量。用add_regressor这个方法,在建立预测模型之后添加,附加回归量取逻辑值。

def nfl_sunday(ds):
    date = pd.to_datetime(ds)
    if date.weekday() == 6 and (date.month > 8 or date.month < 2):
        return 1
    else:
        return 0
df['nfl_sunday'] = df['ds'].apply(nfl_sunday)
m = Prophet()
m.add_regressor('nfl_sunday')
m.fit(df)
future['nfl_sunday'] = future['ds'].apply(nfl_sunday)
forecast = m.predict(future)
fig = m.plot_components(forecast)

7.预测区间

7.1 趋势不确定性

如果你打印fbprophet的预测结果,你会发现fbprophet是区间预测的。因为预测都是基于历史数据做出的,并且假设了未来数据和历史数据具有相似的变化趋势,这个假设可能会导致预测结果的不准确性。fbprophet提供了一个参数,interval_width,这个参数默认为0.8,越大则说明未来与历史变化趋势更接近。

m = Prophet(interval_width=0.95).fit(df)
future = m.make_future_dataframe(periods=365)
forecast = m.predict(future)

7.2 季节不确定性

季节不确定性通过 mcmc.samples 参数调节,如果大于0做全贝叶斯估计,如果等于0做最大后验估计。谨慎使用啊,非常慢,cpu带不动。

m = Prophet(mcmc_samples=500).fit(df)
future = m.make_future_dataframe(periods=365)
forecast = m.predict(future)

8.异常值

异常值不同于突变点,突变点那是正常波动造成的,异常点是数据有错误,或者统计口径发生了变化导致了数据的激增激降。异常值的存在将使得预测区间编的非常非常大。
处理异常值的最好办法就是删除这个数据,prophet依旧会根据趋势给出预测值,这感觉还不错,怎么删除呢,df赋值为none就好了,不用多说吧。

9.非日数据

有时候我们还需要预估小时级别的数据,这个prophet也是可以处理的,只要你传参是标准的时间戳格式就可以的,唯一要处理的就是外推数据,freq设置为‘H’。
当然月和年的数据是类似的,就是设置freq的问题,其他方法和天级别的预测相似的。

10.诊断

就是交叉验证,sklearn里也有交叉验证,用cross_validation进行。

from fbprophet.diagnostics import cross_validation
df_cv = cross_validation(m, initial='730 days', period='180 days', horizon = '365 days')
#参数意思是730天做阶段,每180天对365天的数据做一个交叉验证,
df_cv.head()

讲到这就基本讲完了,当然对内部机理的介绍还是比较少,我们只要会用就好了。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335

推荐阅读更多精彩内容