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
本教程将需要 pandas
、matplotlib
、numpy
、cython
和 fbprophet
库。 像大多数其他 Python 包一样,我们可以使用 pip 安装 pandas
、numpy
、cython
和 matplotlib
库:
pip install pandas matplotlib numpy cython
为了计算其预测,fbprophet
库依赖于 STAN
编程语言,以纪念数学家 Stanislaw Ulam 命名。 因此,在安装 fbprophet
之前,我们需要确保安装了 pystan
到 STAN
的 Python 包装器:
pip install pystan
完成后,我们可以使用 pip 安装 Prophet:
pip install fbprophet
现在我们都设置好了,我们可以开始使用已安装的包。
第 2 步 — 导入包和加载数据
要开始处理我们的数据,我们将启动 Jupyter Notebook:
jupyter notebook
要创建新的笔记本文件,请从右上角的下拉菜单中选择 New > Python 3:
这将打开一个笔记本,允许我们加载所需的库。
作为最佳实践,首先在笔记本顶部导入您需要的库(注意用于引用 pandas
、matplotlib
和 statsmodels
的标准简写):
%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 显然包含 Month
和 AirPassengers
列。 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 提供了许多引人注目的功能,包括根据用户需求定制预测模型的机会。