如何使用自回归移动平均模型的多变量时间序列

328 阅读13分钟

使用自动自回归移动平均模型的多变量时间序列

时间序列是随时间变化而记录的连续数据点的集合。它有相等的时间间隔,如每小时、每天、每周、每分钟、每月和每年。

时间序列数据的例子包括年度预算、公司销售、天气记录、空中交通、Covid-19案件数量、外汇兑换率和股票价格。

一个时间序列模型分析时间序列值并识别隐藏的模式。最终,该模型根据先前观察到的/历史上的数值,预测未来的时间序列值。

在本教程中,我们将建立一个多变量的时间序列模型。该模型将使用多个变量进行学习。我们使用Auto ARIMA创建模型。

前提条件

读者要理解本教程中解释的时间序列概念,应该了解。

  • [时间序列简介]
  • [时间序列的分解]
  • [构建一个简单的时间序列应用程序]
  • 如何在[Google Colab]中运行Python代码

开始使用Auto ARIMA

Auto ARIMA是一个时间序列库,它可以自动使用ARIMA建立模型的过程。Auto ARIMA在建模和预测中应用了ARIMA的概念。

Auto ARIMA能自动找到ARIMA模型的最佳参数。要跟上这个教程,你必须了解ARIMA模型的概念。

了解ARIMA模型

自回归整合移动平均模型(ARIMA)是一个时间序列模型,它可以识别时间序列值中的隐藏模式并进行预测。例如,ARIMA模型在分析了以前的股票价格后可以预测未来的股票价格。

另外,ARIMA模型假设时间序列数据是静止的。在实施ARIMA模型之前,我们将去除时间序列中的非平稳性成分。

如何去除时间序列中的非平稳性成分

非平稳的时间序列是一个属性随时间变化的序列。一个非平稳的时间序列有趋势和季节性成分。去除时间序列中的非平稳性将使其成为平稳的,并应用ARIMA模型。

应该保持不变的时间序列的属性是方差和平均值。让这些属性保持恒定,将消除趋势和季节性成分。我们通过差分来消除时间序列的非平稳性。

差分技术将现在的时间序列值从过去的时间序列值中减去。我们可能不得不多次重复差分过程,直到我们输出一个静止的时间序列。

一个ARIMA模型有三个首字母。AR, I, 和MA。这些首字母代表构成一个统一模型的三个子模型。首字母的功能如下。

解释ARIMA的首字母

AR--自动回归。I - 综合。MA--移动平均。

它们有以下功能。

  • 自动回归子模型--该子模型使用过去的数值来进行未来的预测。

  • 综合子模型--该子模型进行差分,以消除时间序列中的任何非平稳性。

  • 移动平均值子模型。- 它使用过去的误差来进行预测。

这些子模型是整个ARIMA模型的参数。我们使用以下独特的符号来初始化参数。

  • p:它是自动回归(AR)子模型的顺序。它指的是模型用来进行预测的过去值的数量。

  • d:它是为消除非平稳成分而进行的差分次数。

  • q:它是移动平均数(MA)子模型的顺序。它指的是ARIMA模型在进行预测时,可以有多少个过去的错误。

为什么我们要使用Auto ARIMA?

在我们建立ARIMA模型之前,我们通过p,d和q值。我们使用统计图和技术来寻找这些参数的最佳值。

我们还使用统计图,如部分自相关函数图自动相关函数图

使用统计图的过程通常是忙碌和耗时的。许多人在解释这些图以找到最佳参数值时遇到了困难。错误的解释导致人们无法得到最佳/最优的p、d和q值。这影响了ARIMA模型的整体性能。

Auto ARIMA自动生成最佳参数值(p,d,和q)。生成的值是最好的,模型将给出准确的预测结果。

Auto ARIMA简化了使用ARIMA模型建立时间序列模型的过程。现在我们知道了ARIMA的工作原理和Auto ARIMA如何应用其概念。我们将开始探索时间序列数据集。

能源消耗数据集

我们将使用能源消耗数据集来建立自回归管理模型。该数据集显示了从2012年到2017年以小时为间隔记录的能源需求。

使用这个链接下载时间序列数据集。下载时间序列数据集后,我们将使用Pandas 库加载它。

import pandas as pd

为了加载能源消耗数据集,运行这段代码。

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

要将数据集可视化,请使用这段代码。

df

能源消耗数据集的输出。

Energy consumption dataset

从这个输出中,我们有timeStamp,demand,precip, 和temp 列。这些列是将建立时间序列模型的变量。

该时间序列是多变量的,因为它有三个时间因变量 (demand,precip, 和temp) 。它们具有以下功能。

  • timestamp 栏显示记录的时间。
  • demand 栏显示每小时的能源消耗。
  • preciptemp 栏与demand 栏相关。

转换timestamp

我们需要将timestamp 列转换为DateTime格式。这将使我们能够对该列进行时间序列分析和操作。我们将使用pd.to_datetime 函数。

df['timeStamp']=pd.to_datetime(df['timeStamp'])

绘制demand 列的图形

由于我们正在预测demand ,我们绘制这一列以可视化数据点。这将使我们能够检查时间序列中的趋势或季节性。我们将使用Plotly Express Python模块来绘制线形图。

我们导入Plotly Express Python模块如下。

import plotly.express as px

要绘制demand 列,使用以下代码。

fig = px.line(df, x='timeStamp', y='demand', title='Energy Consumption')

fig.update_xaxes(
    rangeslider_visible=True,
    rangeselector=dict(
        buttons=list([
            dict(step="all")
        ])
    )
)
fig.show()

它绘制了以下的折线图。

Energy consumption plot

从上面的输出来看,数据集具有季节性(重复的周期)。由于数据集具有季节性,我们可以说它是非平稳的。但是,我们仍然需要使用Augmented Dickey-Fuller(ADF)测试进行统计检查,以评估我们数据集的静止性。该测试更准确。

如果我们在ADF检验后发现数据集是非平稳的,我们将不得不进行差分以使其成为平稳的。Auto ARIMA会自动进行差分。下一步是将timeStamp 作为索引列。

el_df=df.set_index('timeStamp')

我们将timeStamp 作为索引列是为了更好地与数据框架互动。Auto ARIMA模型也希望将timeStamp 作为索引列。

绘制子图

子图将显示数据集中随时间变化的变量。我们将把demand,precip, 和temp 列可视化。

el_df.plot(subplots=True)

它产生以下子图。

Subplots

检查缺失值或空值

我们需要检查数据集中的缺失值。缺失值会影响模型并导致不准确的预测结果。

print ("\nMissing values :  ", df.isnull().any())

输出。

Checking missing values

从输出结果来看,所有的列都有缺失值。我们将使用数据归置法来处理缺失值。它确保我们有一个完整的时间序列数据集。

归纳缺失值

我们将首先对demand 列中的缺失值进行估算。我们将使用fillna 方法。

归纳'需求'列

df['demand']=df['demand'].fillna(method='ffill')

归纳'温度'列

df['temp']=df['temp'].fillna(method='ffill')

归纳'降水'列

df['temp']=df['precip'].fillna(method='ffill')

我们再次检查缺失值,以了解我们是否成功处理了这个问题。

print ("\nMissing values :  ", df.isnull().any())

Checking missing values

数据集重新取样

时间序列有许多数据点,可能难以分析和可视化。我们需要通过压缩和汇总到每月的时间间隔来重新取样。我们将有更少的数据点,更容易进行分析。

resample() 方法将聚合时间序列中的所有数据点,并将其改为月度间隔。

el_df.resample('M').mean()

数据集重新取样输出。

Dataset resampling

让我们来绘制重新采样的数据集的新子图。

绘制新的子图

我们绘制新的子图,如下所示。

el_df.resample('M').mean().plot(subplots=True)

New subplots

从这些新的子图来看,我们已经对数据集进行了重新采样。对这些较少的数据点进行建模会比较容易。我们将把重新取样的数据集保存在一个新的变量中。

保存重新取样的数据集

我们保存重新采样的数据集如下。

final_df=el_df.resample('M').mean()

我们将使用这个数据集来训练时间序列模型。我们现在可以开始实现自回归管理模型了。

实现自适应移动平均模型

我们使用pmdarima时间序列库来实现Auto ARIMA模型。这个库提供了auto_arima() 函数,可以自动生成最佳参数值。

要安装pmdarima ,使用这个命令。

!pip install pmdarima

安装完成后,我们将其导入,如下所示。

import pmdarima as pm

下一步是初始化auto_arima() 函数。

初始化自动阿里马函数

我们初始化auto_arima() 函数,如下所示。

model = pm.auto_arima(final_df['demand'], 
                        m=12, seasonal=True,
                      start_p=0, start_q=0, max_order=4, test='adf',error_action='ignore',  
                           suppress_warnings=True,
                      stepwise=True, trace=True)

auto_arima() 函数中,我们传递final_df ,这是我们重新采样的数据集。我们选择demand 列,因为这是模型想要预测的内容。

该函数可以使用网格搜索技术,或随机搜索技术来寻找最佳参数值。它尝试了p、d和q的多种组合,然后选择最优的组合。

auto_arima() 函数也有以下参数。

  • m=12 - 它代表一年中的月数。

  • start_p=0 - 它代表该函数在随机搜索过程中可以选择的最小 值。p

  • start_q=0 - 它代表函数在随机搜索过程中可以选择的最小 值。q

  • max_order=4 - 它代表了模型在随机搜索过程中可以选择的最大 、 和 值。p d q

  • test='adf' - 它是一个Augmented Dickey-Fuller(ADF)测试,用来检查我们的数据集的静止性。如果经过ADF检验的数据集是非稳态的, 函数将自动生成 值进行差分。如果数据集是静止的,它会设置d=0(不需要差分)。auto_arima() d

  • suppress_warnings=True - 它忽略了参数搜索过程中的警告。

  • stepwise=True - 它将运行随机搜索来寻找最佳参数。网格搜索是更详尽的,因为它尝试了所有的参数组合,但它很慢。我们选择使用随机搜索,因为它比较快。

当你运行这段代码时,该函数将随机搜索参数并产生以下输出。

Auto ARIMA output

从上面的输出来看,最佳模型是ARIMA(1,0,1)(p=1,d=0,q=1)。该函数自动设置d=0,因为ADF检验发现该数据集是静止的。

我们之前观察到时间序列数据集的图有季节性。因此,我们认为时间序列是非稳态的,因此需要进行差分。

但使用ADF检验,也就是统计检验,发现季节性不明显。ADF检验比观察/看图说话更准确。这就是为什么该函数设置d=0,而且不需要进行差分。

在初始化auto_arima() 函数后,下一步是分割时间序列数据集。

分割时间序列数据集

我们将时间序列数据集分割成一个训练数据框和一个测试数据框,如下所示。

train=final_df[(final_df.index.get_level_values(0) >= '2012-01-31') & (final_df.index.get_level_values(0) <= '2017-04-30')]

代码选择2012-01-31至2017-04-30的数据点进行模型训练。我们用以下代码得到用于模型测试的数据点。

test=final_df[(final_df.index.get_level_values(0) > '2017-04-30')]

2017-04-30的数据点是用于模型测试的。为了显示测试数据点,使用这段代码。

test

Test data frame

从输出结果来看,测试数据框有四个数据点。

让我们将Auto ARIMA模型拟合到训练数据框中。

拟合自回归移动平均模型

拟合Auto ARIMA模型到训练数据框将使模型能够从时间序列数据集中学习。最终的模型将对未来进行预测。

model.fit(train['demand'])

训练后,它产生以下输出。

Auto ARIMA training

我们使用训练数据框来训练模型。在训练过程中,它还使用最佳的p、d和q参数值。让我们使用该模型来进行预测。

使用Auto ARIMA模型来进行预测

Auto ARIMA模型将使用测试数据框进行预测。它也会预测/预报未见过的未来时间序列值。

预测测试数据框架

我们对测试数据框的预测如下。

forecast=model.predict(n_periods=4, return_conf_int=True)
  • n_periods=4:它表示模型将预测的测试数据框中的数据点的数量。要查看预测值,请使用此代码。
forecast

Predicted values

我们需要将预测值转换为Pandas数据框。使用Matplotlib绘制Pandas数据框会更容易。

forecast_df = pd.DataFrame(forecast[0],index = test.index,columns=['Prediction'])

要查看Pandas数据框,请运行这段代码。

forecast_df

它会产生这样的输出。

Pandas data frame

下一步是用Matplotlib绘制Pandas数据框。

绘制Pandas数据框架

我们导入Matplotlib,如下所示。

import matplotlib.pyplot as plt

我们绘制折线图,如下所示。

pd.concat([final_df['demand'],forecast_df],axis=1).plot()

它产生的折线图如下。

Line chart

从上面的折线图来看。

  • 蓝线是实际的能源需求。
  • 橙色的线是预测的能源需求。

Auto ARIMA模型表现良好,并作出了准确的预测。蓝线和橙线相互接近。

我们现在可以用这个模型来预测未见的未来值。

预测未见过的未来时间序列值

为了预测/预报未见过的未来值,请使用这个代码。

forecast1=model.predict(n_periods=8, return_conf_int=True)
forecast_range=pd.date_range(start='2017-05-31', periods=8,freq='M')
  • n_periods=8 它代表了模型将在未来预测的数据点的数量。未来的日期是从2017-05-31开始。我们还需要将预测值转换为Pandas数据框。
forecast1_df = pd.DataFrame(forecast1[0],index =forecast_range,columns=['Prediction'])

最后,我们用Matplotlib绘制未来的预测值

绘制未来的预测值

要绘制未来的预测值,请使用以下代码。

pd.concat([final_df['demand'],forecast1_df],axis=1).plot()

它产生了以下的折线图。

Prediction line chart

从上面的折线图来看。

  • 蓝线代表实际的能源需求。
  • 橙色的线代表预测的能源需求。

橙色线也显示了未见的未来预测值。Auto ARIMA模型表现良好,因为橙线保持了一般模式。

总结

在本教程中,我们已经学会了如何用Auto ARIMA建立一个多变量时间序列模型。我们探讨了Auto ARIMA模型是如何工作的,以及它如何自动找到ARIMA模型的最佳参数。

最后,我们实现了Auto ARIMA模型。我们用Auto ARIMA模型找到了p,d, 和q 的值。

我们用训练好的自回归模型来预测测试数据框架的能源需求和未见过的未来时间序列值。最终的模型做出了准确的预测,在绘制的线图中观察到。