Python3中使用Prophet进行时间序列预测的指南

来自菜鸟教程
跳转至:导航、​搜索

介绍

在之前的教程中,我们展示了 如何可视化和操作时间序列数据 ,以及 如何利用 ARIMA 方法从时间序列数据中生成预测 。 我们注意到 ARIMA 模型的正确参数化可能是一个复杂的手动过程,需要一定的时间。

其他统计编程语言,如 R 提供 自动化方式 来解决这个问题,但尚未正式移植到 Python。 幸运的是,Facebook 的核心数据科学团队最近发布了一种名为 Prophet 的新方法,该方法使数据分析师和开发人员能够在 Python 3 中进行大规模预测。

先决条件

本指南将介绍如何在本地桌面或远程服务器上进行时间序列分析。 处理大型数据集可能会占用大量内存,因此无论哪种情况,计算机都需要至少 2GB 内存 来执行本指南中的一些计算。

在本教程中,我们将使用 Jupyter Notebook 来处理数据。 如果您还没有它,您应该按照我们的 教程安装和设置适用于 Python 3 的 Jupyter Notebook。

第 1 步 — 拉取数据集并安装包

为了使用 Prophet 设置我们的时间序列预测环境,让我们首先进入我们的本地编程环境或基于服务器的编程环境:

cd environments
. my_env/bin/activate

从这里,让我们为我们的项目创建一个新目录。 我们将它命名为timeseries,然后进入目录。 如果您使用不同的名称命名项目,请务必在整个指南中用您的名称替换 timeseries

mkdir timeseries
cd timeseries

我们将使用 Box and Jenkins (1976) Airline Passengers dataset,其中包含 1949 年至 1960 年间每月航空公司乘客数量的时间序列数据。 您可以通过使用带有 -O 标志的 curl 命令将输出写入文件并下载 CSV 来保存数据:

curl -O https://assets.digitalocean.com/articles/eng_python/prophet/AirPassengers.csv

本教程将需要 pandasmatplotlibnumpycythonfbprophet 库。 像大多数其他 Python 包一样,我们可以使用 pip 安装 pandasnumpycythonmatplotlib 库:

pip install pandas matplotlib numpy cython

为了计算其预测,fbprophet 库依赖于 STAN 编程语言,以纪念数学家 Stanislaw Ulam 命名。 因此,在安装 fbprophet 之前,我们需要确保安装了 pystanSTAN 的 Python 包装器:

pip install pystan

完成后,我们可以使用 pip 安装 Prophet:

pip install fbprophet

现在我们都设置好了,我们可以开始使用已安装的包。

第 2 步 — 导入包和加载数据

要开始处理我们的数据,我们将启动 Jupyter Notebook:

jupyter notebook

要创建新的笔记本文件,请从右上角的下拉菜单中选择 New > Python 3

这将打开一个笔记本,允许我们加载所需的库。

作为最佳实践,首先在笔记本顶部导入您需要的库(注意用于引用 pandasmatplotlibstatsmodels 的标准简写):

%matplotlib inline
import pandas as pd
from fbprophet import Prophet

import matplotlib.pyplot as plt
plt.style.use('fivethirtyeight')

请注意,我们还如何为我们的绘图定义了 Fivethirtyeight matplotlib 样式

在本教程中的每个代码块之后,您应该键入 ALT + ENTER 以运行代码并移动到笔记本中的新代码块。

让我们从读入我们的时间序列数据开始。 我们可以使用以下命令加载 CSV 文件并打印出前 5 行:

df = pd.read_csv('AirPassengers.csv')

df.head(5)

我们的 DataFrame 显然包含 MonthAirPassengers 列。 Prophet 库需要一个 DataFrame 作为输入,其中一列包含时间信息,另一列包含我们希望预测的指标。 重要的是,时间列应该是 datetime 类型,所以让我们检查一下列的类型:

df.dtypes
OutputMonth            object
AirPassengers     int64
dtype: object

因为 Month 列不是 datetime 类型,我们需要转换它:

df['Month'] = pd.DatetimeIndex(df['Month'])
df.dtypes
OutputMonth            datetime64[ns]
AirPassengers             int64
dtype: object

我们现在看到我们的 Month 列是正确的 datetime 类型。

Prophet 还强加了输入列命名为 ds(时间列)和 y(度量列)的严格条件,所以让我们重命名 DataFrame 中的列:

df = df.rename(columns={'Month': 'ds',
                        'AirPassengers': 'y'})

df.head(5)

可视化我们将要使用的数据是一种很好的做法,所以让我们绘制我们的时间序列:

ax = df.set_index('ds').plot(figsize=(12, 8))
ax.set_ylabel('Monthly Number of Airline Passengers')
ax.set_xlabel('Date')

plt.show()

现在我们的数据准备好了,我们准备使用 Prophet 库来生成我们时间序列的预测。

第 3 步——使用 Prophet 进行时间序列预测

在本节中,我们将描述如何使用 Prophet 库来预测我们时间序列的未来值。 Prophet 的作者已经抽象出时间序列预测的许多固有复杂性,并使分析师和开发人员更直观地处理时间序列数据。

首先,我们必须实例化一个新的 Prophet 对象。 Prophet 使我们能够指定许多参数。 例如,我们可以通过设置 interval_width 参数来指定我们的不确定区间的期望范围。

# set the uncertainty interval to 95% (the Prophet default is 80%)
my_model = Prophet(interval_width=0.95)

现在我们的 Prophet 模型已经初始化,我们可以调用它的 fit 方法,并将我们的 DataFrame 作为输入。 模型拟合应该不超过几秒钟。

my_model.fit(df)

您应该会收到与此类似的输出:

Output<fbprophet.forecaster.Prophet at 0x110204080>

为了获得我们时间序列的预测,我们必须为 Prophet 提供一个新的 DataFrame,其中包含一个 ds 列,其中包含我们想要预测的日期。 方便的是,我们不必担心手动创建这个 DataFrame,因为 Prophet 提供了 make_future_dataframe 辅助函数:

future_dates = my_model.make_future_dataframe(periods=36, freq='MS')
future_dates.tail()

在上面的代码块中,我们指示 Prophet 在未来生成 36 个日期戳。

在使用 Prophet 时,重要的是要考虑我们的时间序列的频率。 因为我们处理的是月度数据,所以我们明确指定了所需的时间戳频率(在本例中,MS 是月份的开始)。 因此,make_future_dataframe 为我们生成了 36 个每月的时间戳。 换句话说,我们希望预测未来 3 年时间序列的未来值。

然后将未来日期的 DataFrame 用作我们拟合模型的 predict 方法的输入。

forecast = my_model.predict(future_dates)
forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail()

Prophet 返回一个包含许多有趣列的大型 DataFrame,但我们将输出子集为与预测最相关的列,它们是:

  • ds:预测值的时间戳
  • yhat:我们度量的预测值(在统计中,yhat 是传统上用来表示值 y 的预测值的符号)
  • yhat_lower:我们预测的下限
  • yhat_upper:我们预测的上限

由于 Prophet 依赖马尔可夫链蒙特卡洛 (MCMC) 方法来生成其预测,因此可以预期上述输出中的值会发生变化。 MCMC 是一个随机过程,因此每次的值都会略有不同。

Prophet 还提供了一个方便的功能来快速绘制我们的预测结果:

my_model.plot(forecast,
              uncertainty=True)

Prophet 绘制了我们时间序列的观测值(黑点)、预测值(蓝线)和我们预测的不确定区间(蓝色阴影区域)。

Prophet 的另一个特别强大的功能是它能够返回我们预测的组成部分。 这可以帮助揭示时间序列的每日、每周和每年模式对整体预测值的贡献:

my_model.plot_components(forecast)

上图提供了有趣的见解。 第一个图显示,航空公司乘客的每月数量随着时间的推移呈线性增长。 第二个图突出了这样一个事实,即每周的乘客数量在周末和周六达到峰值,而第三个图显示,7 月和 8 月的假期期间客流量最多。

结论

在本教程中,我们描述了如何使用 Prophet 库在 Python 中执行时间序列预测。 我们一直在使用开箱即用的参数,但 Prophet 使我们能够指定更多参数。 特别是,Prophet 提供了将您自己关于时间序列的知识带到桌面上的功能。

以下是您可以尝试的其他一些操作:

  • 通过包含您对假期月份的先验知识来评估假期的影响(例如,我们知道 12 月份是假期月份)。 建模假期的官方文档会有所帮助。
  • 更改不确定区间的范围,或进一步预测未来。

如需更多练习,您还可以尝试加载另一个时间序列数据集以生成您自己的预测。 总体而言,Prophet 提供了许多引人注目的功能,包括根据用户需求定制预测模型的机会。