如何使用ARIMA/SARIMA的单变量时间序列分析和预测

280 阅读14分钟

用ARIMA/SARIMA进行单变量时间序列分析和预测

时间序列是在固定的时间间隔内发生的数据点的序列。一个时间序列显示了数据集中所有与时间有关的变量。时间序列数据的一个例子是股票价格和天气记录。

在时间序列分析和建模中,我们训练模型来识别数据集中的模式。时间序列预测涉及寻找时间序列的未来值。

一个时间序列可以是单变量,双变量,或多变量。单变量的时间序列只有一个变量,双变量有两个变量,而多变量有两个以上的变量。

在本教程中,我们将处理单变量时间序列的建模问题。我们将首先讨论ARIMA和季节性ARIMA模型的一些概念。然后我们将实际地实现ARIMA和季节性ARIMA模型。

前提条件

为了轻松地学习本教程,读者应该了解以下内容。

  • [时间序列的概念]
  • [时间序列分析和建模]
  • [时间序列的应用]
  • [时间序列模式]
  • [时间序列图]

注意:确保你在Gooogle Colab中实现ARIMA和SARIMA模型。

ARIMA模型是如何工作的

自回归整合移动平均模型(ARIMA)是一个时间序列模型,它使用过去时间序列值中的信息来进行未来的预测。在过去的数值中发现的信息将表明未来预测的性质。例如,ARIMA模型可以在观察和分析以前的股票价格后预测未来的股票价格。

ARIMA模型将使用时间序列中的单一时间相关(单变量)变量进行预测。ARIMA模型只有在时间序列是静止的情况下才能发挥作用。

什么是静止的时间序列?

静止的时间序列是一个属性随时间保持不变的序列。这些属性是方差、平均值和协方差。静止的时间序列没有趋势和重复的周期/季节性。大多数时间序列是非平稳的,特别是股票价格和其他金融数据。

为了使ARIMA模型发挥作用,我们必须使数据成为静止的。我们去除趋势和季节性。这将使ARIMA模型更容易做出预测。为了使一个时间序列静止,我们应用差分技术。

什么是差分?

差分是使一个时间序列静止的过程。它是数据集预处理的一个重要步骤。它使时间序列的方差、协方差和平均数保持不变。它还可以减少时间序列数据中的重复周期和季节性成分。

差分技术找到了当前时间序列值与先前值之间的差异。我们可能会得到一次时间序列值之间的差异,但仍然不能使时间序列静止。在这种情况下,我们需要多次寻找差值,直到时间序列成为静止的。

ARIMA模型的组成部分

ARIMA模型是由三个部分组成的。它们结合起来形成最终的ARIMA模型。

这些组成部分如下。

  1. 自动回归
  2. 综合
  3. 移动平均

自动回归

它使用时间序列中以前的时间序列值来进行未来预测。它利用当前时间序列值与过去观测值之间的依赖关系。

综合

该组件执行差分,使时间序列静止。它从以前的时间序列值中减去当前的时间序列值。

移动平均

它使用过去预测的误差来进行未来预测。它使用一个实际的时间序列值和以前的模型误差之间的依赖关系。

当创建一个ARIMA模型时,我们使用以下标准符号将每个组件作为参数传递。p,d, 和q 。它们代表构建ARIMA模型的参数。我们将ARIMA模型初始化为ARIMA(p,d,q)。

标准符号的功能如下。

  • p:它代表自动回归(AR)成分的顺序。它代表在ARIMA模型中发现的滞后观测值的数量。滞后是时间序列中两个数据点/观测值之间的时间间隔。我们使用部分自相关函数(PACF)图得到最佳值p

  • d:它是为使时间序列静止而进行的总差分步骤。如果时间序列数据已经是静止的,就不需要进行差分。

  • q:它代表移动平均(MA)成分的顺序。它显示了最终ARIMA模型应该有的预测误差。我们使用自动相关函数(ACF)图得到最佳值q

注意:时间序列中的阶数是指模型用来进行一次预测的先前观测值/时间序列值的数量。

如何检查静止性

我们将对时间序列图进行可视化,并进行统计测试以检查静止性。

时间序列图的可视化

这需要将时间序列图(线图)可视化,以检查趋势或季节性。

执行统计测试

这需要对时间序列进行统计测试以检查静止性。我们使用各种统计工具进行这种测试。在本教程中,我们将使用Augmented Dickey-Fuller工具。

扩增的迪克-富勒测试

我们将实施Augmented Dickey-Fuller(ADF)检验来检查静止性。ADF检验使用假设检验来检查静止性。它有一个无效假设和一个替代假设。该检验的无效假设是,时间序列是非平稳的。备选假设是,时间序列是静止的。

ADF检验有一个重要的参数,称为p-value ,它决定了一个时间序列是否是静止的。当p-value 小于0.05时,该时间序列是静止的。

SARIMA如何工作

季节性自回归整合移动平均模型(Seasonal ARIMA)是ARIMA模型的一个子集,支持对具有季节性/重复周期的时间序列进行直接建模。

我们也将使用ARIMA模型的参数(p,d,q)实现SARIMA。然后我们添加一些新的参数来处理重复周期或季节性。新增加的参数是:P,Q,D, 和s 。我们将SARIMA模型初始化为SARIMA(p,d,q)(P, D, Q, s)。

  • D:它代表了时间序列中的季节性差异步骤的数量。
  • Q:代表季节性移动平均成分的顺序。
  • P:代表季节性自回归成分的顺序。
  • s:代表每个季节性成分中的时期。一年中的周期(月)数为12,s=12。

SARIMA使用D 参数处理季节性问题。它执行季节性差分。它减去了季节性成分中的数据点。下一步是开始建立我们的模型。

时间序列数据集

我们将准备销售数据集。该数据集将建立一个时间序列模型,预测每月的香槟酒销量。该数据集显示了从1964年到1972年的月度销售额。我们将在训练数据集上建立模型,并使用测试数据集进行预测。

加载数据集

我们将使用Pandas 库来加载数据集。

python
import pandas as pd

使用这段代码来读取数据。

python
df = pd.read_csv('monthly-sales.csv')

要显示数据集的前五个数据点,使用这段代码。

python
df.head()

前五个数据点。

First five

要显示数据集的最后五个数据点,请使用这段代码。

python
df.tail()

最后五个数据点。

Last five

从这个输出中,第105个和第106个数据点/行有缺失值。我们将不得不放弃这些数据点。我们还必须重新命名这些列。

重命名列

要重新命名这些列,请使用这段代码。

python
df.columns=["Month","Sales"]
df.head()

重命名后的列的输出。

New column names

丢弃数据点

要删除第105和106个数据点/行,请使用这段代码。

python
df.drop(,axis=0,inplace=True)
df.drop(,axis=0,inplace=True)
df.tail()

输出。

Dropping the rows

我们已经放弃了这些行。新的数据集现在将有104个数据点/行。

转换 "月 "列

我们需要将month 列转换为DateTime 格式。这种格式允许我们进行时间序列分析。我们将使用pd.to_datetime 函数。

python
df['Month']=pd.to_datetime(df['Month'])

要查看转换后的month 列,请运行此代码。

python
df.head()

输出。

Columns

我们还需要将month 列设置为索引列。使用这段代码。

python
df.set_index('Month',inplace=True)

要查看新的变化,运行这段代码。

python
df.head()

输出。

Index column

时间序列数据的可视化

我们将绘制时间序列数据,并检查趋势或季节性/重复的周期。如前所述,这是一个检查时间序列静止性或非静止性的简单方法。我们将使用Matplotlib 进行绘图。

python
import matplotlib.pyplot as plt

为了绘图,运行这段代码。

python
df.plot()

它产生以下的线图。

Line chart

该折线图将salesmonth 。通过可视化,时间序列具有季节性或重复的周期。在一年中的某些月份,高峰和低谷不断地重复出现。

我们可以得出结论,该时间序列是非平稳的,因为它具有季节性。我们仍然需要对时间序列进行统计测试来证明这种非平稳性。如前所述,我们将使用Augmented Dickey-Fuller检验。

实现Augmented Dickey-Fuller检验

我们导入Augmented Dickey-Fuller工具如下。

python
from statsmodels.tsa.stattools import adfuller

我们初始化adfuller 函数并传递sales 列,如下所示。

python
passing_data=adfuller(df['Sales'])

我们将创建一个函数来检查数据集的静止性。我们只需要证明我们之前在折线图上观察到的情况。

python
def adf_test(sales):
    result=adfuller(sales)
    labels = ['Test parameters', 'p-value','#Lags Used','Dataset observations']
    for value,label in zip(result,labels):
        print(label+' : '+str(value) )
    if result[1] <= 0.05:
        print("Dataset is stationary")
    else:
        print("Dataset is non-stationary ")

ADF检验将检查静止性。p-value 将确定时间序列是否是静止的。当ADF检验的p-value 小于0.05时,那么时间序列是静止的。然后我们将函数应用于Sales 列,以了解ADF检验的结果,并得到p-value

应用该函数

要应用该函数,请使用此代码。

python
adf_test(df['Sales'])

它产生的结果如下。

ADF test results

从上面的输出中,我们有不同的输出值,显示了我们数据集的性质。我们只对p-value 的结果感兴趣。p-value 是0.363915771660247。

这个数字大于0.05。这意味着时间序列是非平稳的。我们将不得不使用差分方法使时间序列静止。

实施差分法

这种方法可以找到时间序列中当前月度值和前一个月度值之间的差异。我们将只差一次,因此我们的d=1

python
df['Differencing']=df['Sales']-df['Sales'].shift(12)

这段代码将差分sales 值。

我们再次进行Augmented Dickey-Fuller检验,以检查时间序列是否成为静止的。

python
adf_test(df['Differencing'].dropna())

检验结果。

ADF test results

从测试结果来看,p-value 是2.519620447387081e-10(0.0000000002519620447387081)。这个数字<0.05,因此数据集已经成为静止的。我们将绘制这个新的时间序列,看看我们是否已经去除季节性成分。

绘制新的数据集

要绘制新的数据集,请使用这段代码。

python
df['Differencing'].plot()

New dataset plot

从上面的输出来看,我们已经删除了季节性成分。我们可以开始对数据集应用ARIMA模型。

实施ARIMA模型

如前所述,我们将ARIMA模型初始化为ARIMA(p,d,q)。所以我们需要得到这些参数的值。我们已经讨论过每个参数的功能。

我们已经知道d=1 。这是因为我们只进行了一次差分。下一步是获得最佳的pq 值。

获得最佳的'p'和'q'值

我们使用自相关函数(ACF)图得到q 的最佳值。

我们使用部分自相关函数(PACF)图得到p 的最佳值。

让我们导入PACFACF

python
from statsmodels.graphics.tsaplots import plot_acf,plot_pacf
import statsmodels.api as sm

然后我们首先绘制ACF,如下所示。

绘制ACF图

要绘制ACF,请使用这段代码。

python
ax1 = fig.add_subplot(211)
fig = sm.graphics.tsa.plot_acf(df['Differencing'].iloc[13:],lags=40,ax=ax1)

上面的代码产生了下面的图。

ACF plot

我们将用这个图来得到q 的最佳值。从ACF图上看,滞后1号很突出。红色箭头显示了滞后点。它略高于(切断)重要性线(蓝线)。我们将选择这个滞后点作为q 的最佳值。因此,q=1

绘制PACF图

要绘制PACF,请使用此代码。

python
ax2 = fig.add_subplot(212)
fig = sm.graphics.tsa.plot_pacf(df['Differencing'].iloc[13:],lags=40,ax=ax2)

它产生了下面的图。

PACF plot

我们将使用这个图来获得最佳值p 。从PACF图中,我们可以观察到滞后1和13很突出。红色箭头显示了滞后点。

这些点在重要性线(蓝色阴影线)之上(切断)。我们选择滞后1号作为p 的最佳值。它是第一个高于蓝线的滞后点。因此,p=1

我们的数值将是。p=1,d=1q=1 。下一步是导入ARIMA模型。

导入ARIMA模型

我们导入ARIMA模型的方法如下。

python
from statsmodels.tsa.arima_model import ARIMA

我们初始化模型如下。

python
model=ARIMA(df['Sales'],order=(1,1,1))

训练ARIMA模型

我们使用fit 函数来训练ARIMA模型。ARIMA模型将从时间序列数据集中学习。

python
arima_model=model.fit()

我们已经训练了ARIMA模型。我们可以用它来预测测试数据集。预测结果将显示每月的实际销售额和预测(预测)销售额。

使用测试数据集测试ARIMA模型

我们将使用从第90行到第103行的数值作为测试部分/集。然后我们将使用Matplotlib 来显示实际和预测(预测)的月销售额。

python
df['forecast']=arima_model.predict(start=90,end=103,dynamic=True)
df[['Sales','forecast']].plot(figsize=(12,8))

它产生的线图如下。

ARIMA line-chart

从上面的输出来看。

  • 蓝线是实际月销售额。
  • 橙色的线是预测的销售额。

ARIMA模型表现不佳,因为它没有做出正确的预测。橙色的线与蓝色的线相差甚远。我们现在将使用SARIMA建立另一个时间序列模型来提高性能。

实现SARIMA模型

SARIMA将处理和模拟具有重复周期或季节性的时间序列数据。从先前的ADF测试来看,数据集具有季节性。我们将SARIMA模型初始化为SARIMA(p,d,q)(P, D, Q, s)。我们已经有了p,d, 和q 的值。

我们可以用同样的方法得到P,D,Q 。因此,p=P,q=Q,d=D。s=12 ,因为一年有12个月。我们将SARIMA模型初始化如下。

python
model=sm.tsa.statespace.SARIMAX(df['Sales'],order=(1, 1, 1),seasonal_order=(1,1,1,12))

训练SARIMA模型

我们使用fit 函数来训练SARIMA模型。SARIMA模型将从时间序列数据集中学习。

python
sarima_model=model.fit()

我们已经训练了SARIMA模型。我们可以用它来预测测试数据集。预测结果将显示每月的实际销售额和预测销售额。

使用测试数据集测试SARIMA模型

我们也将使用第90行到第103行的数值作为测试部分/集。我们使用Matplotlib 来显示实际和预测(预测)的销售额,如下所示。

python
df['forecast']=sarima_model.predict(start=90,end=103,dynamic=True)
df[['Sales','forecast']].plot(figsize=(12,8))

它产生的线图如下。

SARIMA line-chart

从上面的输出来看。

  • 蓝线是每月的实际销售额。
  • 橙色的线是预测的销售额。

时间序列模型做出了正确的预测,因为这两条线是接近的。与ARIMA模型相比,SARIMA模型表现良好。

总结

我们在Python中用ARIMA和SARIMA建立了一个单变量时间序列模型。我们讨论了ARIMA和SARIMA模型如何工作。我们还谈到了时间序列的静止性以及如何使用差分法使序列静止。我们讨论了如何使用Augmented Dickey-Fuller检验来检查静止性。

我们探讨了ARIMA模型的所有组成部分和它们的具体参数。然后我们使用自相关函数(ACF)图和部分自相关函数(PACF)图来获得最佳的pq 值。最后,我们同时实现了ARIMA和SARIMA模型。SARIMA模型做出了更好的预测。