facebook-Prophet-python 预测学习笔记

入门

运用prophet,首先要创建一个prophet类的实例,然后再通过 fitpredict 这两个函数完成基础的预测。快速入门最简单的预测只需要5行代码。

df=pd.read_csv(history_data_path)
m=Prophet()
m.fit(df)
future = m.make_future_dataframe(periods=365)
forecast = m.predict(future)

简介

输入到prophet中的数据要求是Dataframe类型,同时,时间列的标签要命名为 ds ,还要定义成日期YYYY-MM-DD或者时间戳 YYYY-MM-DD HH:MM:SS 这两种Pandas希望获得的格式 。数据列的标签需要命名为 y ,类型一般是数值型(想不到还能是什么类型)。

举个?

1. 引用模块

import pandas as pd
import fbprophet as Prophet

2. 导入数据

df=pd.read_csv(history_data_path)

history_data_path是数据的路径,我使用的是公司的自己的数据
在这里插入图片描述

3. 建立实例并拟合数据

学习(拟合)数据需要先创建一个Prophet类对象,同时可以通过参数来调整它的学习能力。然后再使用fit 函数来让它进行学习拟合。
下面的代码是默认,无更改的Prophet模型。

m=Prophet()
m.fit(df)

下面的代码是根据我寄几的需要,改动后的Prophet模型。

m=Prophet(holidays=holiday,
          yearly_seasonality=True, 
          weekly_seasonality=True,
          daily_seasonality=False,
          holidays_prior_scale=35,
          seasonality_mode='multiplicative')

各种 = 其实就是各种内置参数设定,看着糟心,使用起来并不算困难

  • holidays是节假日信息输入,holiday是一个文件,里面包含有节假日的信息,如下图;
    其实呢,有用的只是dt_ymd和holiday两列,其他的懒得删所以就留着了
    其他的内置参数

  • yearly_seasonality 是年规律拟合,Prophet模型会描绘出以一年为单位的数据规律,后面的部分会有图示;同理于参数 weekly_seasonalitydaily_seasonality

  • n_changepoints 是预设转折点数量

  • changepoint_range 是设定转折点可以存在的范围,.1表示存在于历史数据的前十分之一,.5表示在历史数据的前半部分,其余同理。

  • changepoint_prior_scale 是设置模型对转折点拟合的灵敏度,值越高越灵活。

  • changepoints=[] 是指定转折点的具体位置

  • yearly_seasonality 是年的拟合度,值越高越灵活,同时可以选择True和False来设定是否进行年度的拟合。同理与weekly_seasonalitydaily_seasonality

  • holidays_prior_scale 是假期的拟合度,同样值越高越灵活,同时前提是你需要有假期信息的加入。

  • seasonality_mode=‘multiplicative’ 是模型学习的方式,默认情况下为加性的,如果如上所示来设置,则是乘性的(multiplicative)。

  • 待处理
    m.add_seasonality(name=‘monthly’,period=30.5,fourier_order=5,prior_scale)
    增加季节性规律 预测数量 傅里叶级数 灵活度

4. 生成时间框

我们需要给Prophet提供一个数据框,其中包含有ds,它是一个日期数据列,包含有历史数据的日期和预测的日期。
Prophet为我们提供了生成标准数据框的函数语句,Prophet.make_future_dataframe() ,参数periods设定了预测的天数。

future = m.make_future_dataframe(periods=365)

5. 执行预测

Prophet提供的函数predict会产生一个新的数据框架,其中包含有*Prophet.make_future_dataframe()*生成的所有日期,以及它们对应的预测值,并命名标签为yhat,如果是历史日期,那么会给出模拟对历史数据的拟合值,可以通过它观察模型对历史数据的学习效果。此外返回的新数据框中还包含有预测值的上下界,如果设置了假期因素或者其他的额外因素,那么这些因素对预测的影响也会展示在该数据框中。

forecast = m.predict(future)


描述
加入的因素对预测的影响都可以直观的看到。

6. 可视化

可以通过类中的plot函数绘制图像,给它输入predict函数返回的数据框架,就可以便捷地得到预测图。

m.plot(forecast)

在这里插入图片描述
在这里插入图片描述
此外,还可通过Prophet.plot_components函数绘制图像观察更多的细节。

m.plot_components(forecast)

在这里插入图片描述

饱和预测

增长预测

通常在实际情况下,需要预测的值会存在一个极大值或极小值,而不会是无限增长或者无限下降的,而这个极大或极小的值我们称为== the carrying capaity ==,预测应该在这些值点达到饱和。
Prophet在默认下会使用 linear model ,但是也允许我们使用具有指定 the carrying capaitylogistic model (不会翻译所以copy英文)。

  • 额,这一块没怎么用,先跳过

趋势转折点(Trend Changepoints)

从前面绘制的图中我们可以观察到,时间序列的轨迹(trajectory)会存在一些突兀(abrupt,顺便学英语 :))的转折。Prophet在默认情况下会自动匹配,学习转折点,使预测曲线能适当地预测出转折点。
如果Prophet没能抓住关键的转折点或者说对一些转折点过度拟合,那么,我们能够通过添加一些参数,来更好地把控学习和预测过程。

转折点自动检测

模型会在适应度允许的范围内寻找出大量的潜在转折点,
(以下是谷歌翻译)
然后它在速率变化的幅度上放置一个稀疏的先验(相当于L1正则化) - 这实质上意味着Prophet有大量可能的位置,其中速率可以改变,但将尽可能少地使用它们。 默认情况下,Prophet指定25个潜在的变化点,它们统一放置在前80%的时间序列中。 此图中的垂直线表示潜在变更点的放置位置:
虽然有很多点是速率可能存在改变的点,但是由于稀疏特性,绝大多数的点并没有被最后录用。通过下图可以看到上图中潜在转折点的速率改变。
在这里插入图片描述
在上文中,有过介绍,设置转折点数量的参数n_changepoints
可以通过以下代码显示出转折点的位置:

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

在这里插入图片描述

拟合方式

乘性拟合

默认情况下,Prophet会使用加性季节性,这意味着季节性的影响会会以增加的方式影响到预测的趋势中。
但是对于一些数据,加性并不适合,以下航空旅客数量的时间序列是添加季节性不起作用的一个例子。
在这里插入图片描述

这些以季节为周期倍增的数据,无法用默认的加性拟合。Prophet 则为这种情况提供了 seasonality_mode参数,通过设置 seasonality_mode=‘multiplicative’ 来模拟乘法季节性。

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

需要注意的是,使用 *seasonality_mode=‘multiplicative’*后,假日效果也会变为乘法建模。任何添加的季节性或额外的回归量将默认使用seasonality_mode设置的任何内容,但可以通过在添加季节性或回归量时指定mode='additive’或mode='multiplicative’来覆盖seasonality_mod。

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

上方的代码,Prophet以乘法建模,但是对于额外增加的季节性quarterly和回归量regressor则是加法建模。

季节性,节假日影响和额外回归

节假日和特殊日期建模

如果我们希望Prophet学习一些节假日和会重复出现的特殊日期对时间序列的影响,我们就需要给节假日信息创建一个Dataframe。它要是一个含有holidayds的两列Dataframe
节假日信息必须包含过去和未来,过去的节假日信息用于对数据的学习,未来的节假日信息用于预测。
很容易理解,如果只有历史节假日信息,那么模型会学习这个节假日,但是不知道预测时会出现在哪里。如果只包含未来节假日信息,那么模型根本没办法从历史中学习,就算预测时知道是节假日,也没有办法对它进行调整。
此外,你还可以通过lower_windowupper_window来说明节假日的天数。lower_window只能是负数,表示日期前几天,upper_window反之。对节假日也可以用* prior_scale*来设置它的 the prior scale(这东西没怎么用,所以不是很理解,用文档原文代替)。
节假日信息的输入,可以像Prophet文档那样,在python中输入。

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,
})

也可以在文稿中编写,然后用python读入,再转换成Prophet指定的格式。以下是我的节假日文件截图和输入节假日信息的代码:
在这里插入图片描述
需要说明的是,我只选择了第一列和倒数第二列,即dt_ymd,festival。其他列信息都会废弃,有一些甚至是错误的,别理会它们,只需要提取 dt_ymd和festival。

holiday = pd.read_csv('holiday_2016_2018.csv',parse_dates=['dt_ymd'])
holiday = holiday.loc[:, ['dt_ymd', 'holiday']].rename(columns={'dt_ymd':'ds'})
holiday.loc[:, 'lower_window'] = 0
holiday.loc[:, 'upper_window'] = 0

holiday.loc[holiday['holiday'] == '元旦假前', 'lower_window'] = -1
holiday.loc[holiday['holiday'] == '除夕', 'lower_window'] = -3
holiday.loc[holiday['holiday'] == '春节', 'upper_window'] = 5
holiday.loc[holiday['holiday'] == '春节收假', 'upper_window'] = 2

holiday.loc[holiday['holiday'] == '妇女节', 'lower_window'] = -1
holiday.loc[holiday['holiday'] == '520', 'lower_window'] = -1
holiday.loc[holiday['holiday'] == '端午节', 'lower_window'] = -2

holiday.loc[holiday['holiday'] == '国庆节', 'upper_window'] = 6
holiday.loc[holiday['holiday'] == '中秋假前', 'lower_window'] = -1
holiday.loc[holiday['holiday'] == '国庆收假', 'upper_window'] = 4

信息创建成功后,使用Prophet的holidays参数,就可以让模型学习和预测时考虑上节假日因素。
使用方法参见文档的指导代码:

m = Prophet(holidays=holidays)
forecast = m.fit(df).predict(future)
发布了8 篇原创文章 · 获赞 5 · 访问量 2049

猜你喜欢

转载自blog.csdn.net/weixin_38989668/article/details/82845120