目录

引言

  • 时间序列 被定义为在不同时间间隔记录的一系列数据点。时间顺序可以是每日、每月,甚至是每年。

  • 时间序列预测是使用统计模型基于过去结果预测时间序列未来值的过程。

  • 我们在之前的笔记本中讨论了时间序列预测的各个方面。

  • 预测是我们希望预测序列未来值的部分。预测时间序列通常具有巨大的商业价值。

时间序列预测大致可分为两种类型。

  • 如果仅使用时间序列的先前值来预测其未来值,则称为单变量时间序列预测

  • 如果使用除序列本身以外的预测变量(例如外生变量)进行预测,则称为多变量时间序列预测

  • 本笔记本重点介绍一种特定的预测方法,称为 ARIMA 建模

ARIMA 模型简介

  • ARIMA 代表 自回归积分滑动平均模型 (Autoregressive Integrated Moving Average Model)。它属于一类基于自身过去值(即自身滞后值)和滞后预测误差解释给定时间序列的模型。该方程可用于预测未来值。任何显示模式且非随机白噪声的“非季节性”时间序列都可以使用 ARIMA 模型建模。

  • 因此,ARIMA,全称 自回归积分滑动平均 (AutoRegressive Integrated Moving Average),是一种基于时间序列过去值中的信息本身可用于预测未来值的思想的预测算法。

  • ARIMA 模型由三个阶数参数指定:(p, d, q)

    其中,

    • p 是 AR 项的阶数

    • q 是 MA 项的阶数

    • d 是使时间序列平稳所需的差分次数

  • AR(p) 自回归 - 一种回归模型,利用当前观测值与先前时期观测值之间的依赖关系。自回归 (AR(p)) 分量指的是在时间序列的回归方程中使用过去值。

  • I(d) 积分 - 使用观测值的差分(从当前时间步的观测值减去先前时间步的观测值)以使时间序列平稳。差分涉及将序列的当前值与其先前值相减 d 次。

  • MA(q) 滑动平均 - 一种模型,使用观测值与应用于滞后观测值的滑动平均模型的残差误差之间的依赖关系。滑动平均分量将模型的误差描绘为先前误差项的组合。阶数 q 表示要包含在模型中的项数。

ARIMA 模型类型

  • ARIMA : 非季节性自回归积分滑动平均
  • SARIMA : 季节性 ARIMA
  • SARIMAX : 带有外生变量的季节性 ARIMA

如果时间序列具有季节性模式,则需要添加季节性项,它就变成了 SARIMA,全称季节性 ARIMA

ARIMA 模型中 p, d 和 q 的含义

p 的含义

  • p自回归 (AR) 项的阶数。它指代用于预测的 Y 的滞后数。

d 的含义

  • ARIMA 中的“自回归”项意味着它是一个线性回归模型,使用其自身的滞后作为预测变量。众所周知,线性回归模型在预测变量不相关且相互独立时表现最佳。因此我们需要使时间序列平稳。

  • 使序列平稳最常见的方法是进行差分。也就是说,从当前值中减去先前值。有时,根据序列的复杂性,可能需要多次差分。

  • 因此,d 的值是使序列平稳所需的最小差分次数。如果时间序列已经平稳,则 d = 0。

q 的含义

  • q滑动平均 (MA) 项的阶数。它指代应包含在 ARIMA 模型中的滞后预测误差数。

AR 和 MA 模型

AR 模型

在自回归模型中,我们使用变量过去值的线性组合来预测感兴趣的变量。自回归这个术语表明它是变量对自身的回归。

因此,p 阶自回归模型可以写成

yt=c+ϕ1yt1+ϕ2yt2++ϕpytp+εt \begin{equation} y_{t} = c + \phi_{1}y_{t-1} + \phi_{2}y_{t-2} + \dots + \phi_{p}y_{t-p} + \varepsilon_{t} \tag{1} \end{equation}

其中 ϵt\epsilon_t 是白噪声。这就像一个多元回归模型,但使用 yty_t 的滞后值作为预测变量。我们将这称为 AR( p) 模型,一个 p 阶自回归模型。

MA 模型

滑动平均模型不是在回归中使用预测变量的过去值,而是在类似回归的模型中使用过去的预测误差:

yt=c+εt+θ1εt1+θ2εt2++θqεtq \begin{equation} y_{t} = c + \varepsilon_t + \theta_{1}\varepsilon_{t-1} + \theta_{2}\varepsilon_{t-2} + \dots + \theta_{q}\varepsilon_{t-q} \tag{2} \end{equation}

其中 ϵt\epsilon_t 是白噪声。我们将这称为 MA(q) 模型,一个 q 阶滑动平均模型。当然,我们不会观测到
ϵt\epsilon_t 的值,因此它并非通常意义上的回归模型。

注意,可以将每个 yty_t 值视为过去几个预测误差的加权滑动平均(尽管系数通常不总和为一)。然而,滑动平均模型不应与滑动平均平滑混淆。滑动平均模型用于预测未来值,而滑动平均平滑用于估计过去值的趋势周期。

至此,我们分别讨论了 AR 和 MA 模型。

ARIMA 模型

如果我们将差分与自回归和滑动平均模型结合起来,就得到了一个非季节性 ARIMA 模型。ARIMA 是自回归积分滑动平均 (AutoRegressive Integrated Moving Average) 的缩写(在此上下文中,“积分”是差分的逆运算)。完整的模型可以写成

其中 yty'_{t} 是差分后的序列(可能差分过不止一次)。等号右边的“预测变量”包括 yty_t 的滞后值和滞后误差。我们将这称为 ARIMA(p,d,q) 模型,其中

p自回归部分的阶数
d一阶差分的程度
q滑动平均部分的阶数

适用于自回归和滑动平均模型的平稳性和可逆性条件也适用于 ARIMA 模型。

我们已经讨论过的许多模型都是 ARIMA 模型的特殊情况,如表所示

模型p d q差分方法
Arima(0,0,0)0 0 0yt=Yty_t=Y_t白噪声
ARIMA (0,1,0)0 1 0yt=YtYt1y_t = Y_t - Y_{t-1}随机游走
ARIMA (0,2,0)0 2 0yt=Yt2Yt1+Yt2y_t = Y_t - 2Y_{t-1} + Y_{t-2}常数
ARIMA (1,0,0)1 0 0Y^t=μ+Φ1Yt1+ϵ\hat Y_t = \mu + \Phi_1 Y_{t-1} + \epsilonAR(1):一阶回归模型
ARIMA (2, 0, 0)2 0 0Y^t=Φ0+Φ1Yt1+Φ2Yt2+ϵ\hat Y_t = \Phi_0 + \Phi_1 Y_{t-1} + \Phi_2 Y_{t-2} + \epsilonAR(2):二阶回归模型
ARIMA (1, 1, 0)1 1 0Y^t=μ+Yt1+Φ1(Yt1Yt2)\hat Y_t = \mu + Y_{t-1} + \Phi_1 (Y_{t-1}- Y_{t-2})一阶差分自回归模型
自回归模型
ARIMA (0, 1, 1)0 1 1Y^t=Yt1Φ1et1\hat Y_t = Y_{t-1} - \Phi_1 e^{t-1}简单指数
平滑
ARIMA (0, 0, 1)0 0 1Y^t=μ0+ϵtω1ϵt1\hat Y_t = \mu_0+ \epsilon_t - \omega_1 \epsilon_{t-1}MA(1):一阶
回归模型
ARIMA (0, 0, 2)0 0 2Y^t=μ0+ϵtω1ϵt1ω2ϵt2\hat Y_t = \mu_0+ \epsilon_t - \omega_1 \epsilon_{t-1} - \omega_2 \epsilon_{t-2}MA(2):二阶
回归模型
ARIMA (1, 0, 1)1 0 1Y^t=Φ0+Φ1Yt1+ϵtω1ϵt1\hat Y_t = \Phi_0 + \Phi_1 Y_{t-1}+ \epsilon_t - \omega_1 \epsilon_{t-1}ARMA 模型
ARIMA (1, 1, 1)1 1 1ΔYt=Φ1Yt1+ϵtω1ϵt1\Delta Y_t = \Phi_1 Y_{t-1} + \epsilon_t - \omega_1 \epsilon_{t-1}ARIMA 模型
ARIMA (1, 1, 2)1 1 2Y^t=Yt1+Φ1(Yt1Yt2)Θ1et1Θ1et1\hat Y_t = Y_{t-1} + \Phi_1 (Y_{t-1} - Y_{t-2} )- \Theta_1 e_{t-1} - \Theta_1 e_{t-1} 阻尼趋势线性指数平滑
ARIMA (0, 2, 1) 或 (0,2,2)0 2 1Y^t=2Yt1Yt2Θ1et1Θ2et2\hat Y_t = 2 Y_{t-1} - Y_{t-2} - \Theta_1 e_{t-1} - \Theta_2 e_{t-2}线性指数平滑

一旦我们开始以这种方式组合组件来形成更复杂的模型,使用后移算子记法就会容易得多。例如,上述方程可以用后移算子记法写成

文字描述的ARIMA模型

预测值 Yt = 常数 + Y 的滞后项线性组合 (最多 p 个滞后) + 滞后预测误差的线性组合 (最多 q 个滞后)

如何在ARIMA模型中找到差分阶数 (d)

  • 如前所述,差分的目的是使时间序列平稳。但我们要注意不要过度差分。过度差分的序列可能仍然是平稳的,但这会影响模型参数。

  • 所以我们应该确定正确的差分阶数。正确的差分阶数是使序列达到接近平稳所需的最小差分次数,该序列围绕一个确定的均值波动,并且ACF图能相当快地衰减到零。

  • 如果许多滞后项的自相关系数为正(10个或更多),则序列需要进一步差分。另一方面,如果滞后1的自相关系数本身太负,则序列可能过度差分了。

  • 如果我们无法确定两个差分阶数哪个更好,那么我们选择使差分后序列的标准差最小的那个阶数。

  • 现在,我们将通过一个示例如下解释这些概念

    • 首先,我将使用statsmodels包中的增广迪基-福勒检验 (ADF检验)来检查序列是否平稳。原因在于只有当序列非平稳时才需要差分。否则,不需要差分,即 d=0。

    • ADF检验的零假设 (Ho) 是时间序列非平稳。因此,如果检验的p值小于显著性水平 (0.05),我们就拒绝零假设,并推断时间序列确实是平稳的。

    • 因此,在我们的例子中,如果P值 > 0.05,我们将继续寻找差分阶数。

加载库和数据

提示

需要Statsforecast。要安装,请参阅说明

接下来,我们导入绘图库并配置绘图样式。

import matplotlib.pyplot as plt

plt.style.use('fivethirtyeight')
plt.rcParams['lines.linewidth'] = 1.5
dark_style = {
    'figure.facecolor': '#212946',
    'axes.facecolor': '#212946',
    'savefig.facecolor':'#212946',
    'axes.grid': True,
    'axes.grid.which': 'both',
    'axes.spines.left': False,
    'axes.spines.right': False,
    'axes.spines.top': False,
    'axes.spines.bottom': False,
    'grid.color': '#2A3459',
    'grid.linewidth': '1',
    'text.color': '0.9',
    'axes.labelcolor': '0.9',
    'xtick.color': '0.9',
    'ytick.color': '0.9',
    'font.size': 12 }
plt.rcParams.update(dark_style)

from pylab import rcParams
rcParams['figure.figsize'] = (18,7)

读取数据

import pandas as pd
import numpy as np

df = pd.read_csv("https://raw.githubusercontent.com/Naren8520/Serie-de-tiempo-con-Machine-Learning/main/Data/Esperanza_vida.csv", usecols=[1,2])
df.head()
年份
01960-01-0169.123902
11961-01-0169.760244
21962-01-0169.149756
31963-01-0169.248049
41964-01-0170.311707

StatsForecast 的输入始终是长格式的数据框,包含三列:unique_id、ds 和 y

  • unique_id(字符串、整数或类别)表示序列的标识符。

  • ds(时间戳)列应采用 Pandas 期望的格式,日期最好采用 YYYY-MM-DD 格式,时间戳最好采用 YYYY-MM-DD HH:MM:SS 格式。

  • y(数值)表示我们希望预测的度量值。

df["unique_id"]="1"
df.columns=["ds", "y", "unique_id"]
df.head()
dsyunique_id
01960-01-0169.1239021
11961-01-0169.7602441
21962-01-0169.1497561
31963-01-0169.2480491
41964-01-0170.3117071
print(df.dtypes)
ds            object
y            float64
unique_id     object
dtype: object

我们需要将 dsobject 类型转换为 datetime。

df["ds"] = pd.to_datetime(df["ds"])

使用 plot 方法探索数据

使用 StatsForecast 类中的 plot 方法绘制序列。此方法从数据集中打印一个随机序列,对基本 EDA 非常有用。

from statsforecast import StatsForecast

StatsForecast.plot(df)

从图中可以看出,随着时间的推移,存在一个上升趋势。

df["y"].plot(kind='kde',figsize = (16,5))
df["y"].describe()
count    60.000000
mean     76.632439
std       4.495279
           ...    
50%      76.895122
75%      80.781098
max      83.346341
Name: y, Length: 8, dtype: float64

季节性分解

如何以及为何分解时间序列?

在时间序列分析中预测新值时,了解过去的数据非常重要。更正式地说,了解值随时间变化的模式非常重要。有很多原因可能导致我们的预测值偏离正确的方向。时间序列基本上由四个组成部分构成。这些组成部分的变化导致时间序列模式的变化。这些组成部分是

  • 水平分量: 这是随时间平均的主要值。
  • 趋势分量: 趋势是导致时间序列出现递增或递减模式的值。
  • 季节性分量: 这是一种在时间序列中短期出现的周期性事件,导致时间序列出现短期递增或递减模式。
  • 残差/噪声: 这些是时间序列中的随机变化。

随着时间的推移结合这些组成部分,就形成了时间序列。大多数时间序列由水平分量和噪声/残差组成,而趋势或季节性是可选的值。

如果季节性和趋势是时间序列的一部分,那么会影响预测值。因为预测时间序列的模式可能与之前的时间序列不同。

时间序列中组成部分的组合可以是两种类型: * 加法模型 * 乘法模型

加法时间序列

如果时间序列的组成部分是相加而成。那么这种时间序列称为加法时间序列。通过可视化,如果时间序列的递增或递减模式在整个序列中相似,我们可以说它是加法时间序列。任何加法时间序列的数学函数可以表示为: y(t)=level+Trend+seasonality+noisey(t) = level + Trend + seasonality + noise

乘法时间序列

如果时间序列的组成部分是相乘而成,那么这种时间序列称为乘法时间序列。通过可视化,如果时间序列随时间呈现指数增长或下降,则可以将其视为乘法时间序列。乘法时间序列的数学函数可以表示为:

y(t)=LevelTrendseasonalityNoisey(t) = Level * Trend * seasonality * Noise

from statsmodels.tsa.seasonal import seasonal_decompose
decomposed=seasonal_decompose(df["y"], model = "add", period=1)
decomposed.plot()
plt.show()

增广迪基-福勒检验

增广迪基-福勒(ADF)检验是一种统计检验,用于确定时间序列数据中是否存在单位根。单位根可能导致时间序列分析中的不可预测结果。在单位根检验中会形成一个零假设,以确定时间序列数据受趋势影响的强度。通过接受零假设,我们接受时间序列数据不平稳的证据。通过拒绝零假设或接受备择假设,我们接受时间序列数据由平稳过程生成的证据。此过程也称为平稳趋势。ADF检验统计量的值为负。较低的ADF值表明对零假设的拒绝程度更强。

增广迪基-福勒检验是用于检验给定时间序列是否平稳的常用统计检验。我们可以通过定义零假设和备择假设来实现这一点。

零假设:时间序列非平稳。它具有时间依赖的趋势。备择假设:时间序列平稳。换句话说,序列不依赖于时间。

ADF 或 t 统计量 < 临界值:拒绝零假设,时间序列平稳。ADF 或 t 统计量 > 临界值:未能拒绝零假设,时间序列非平稳。

from statsmodels.tsa.stattools import adfuller
def Augmented_Dickey_Fuller_Test_func(series , column_name):
    print (f'Dickey-Fuller test results for columns: {column_name}')
    dftest = adfuller(series, autolag='AIC')
    dfoutput = pd.Series(dftest[0:4], index=['Test Statistic','p-value','No Lags Used','Number of observations used'])
    for key,value in dftest[4].items():
        dfoutput['Critical Value (%s)'%key] = value
    print (dfoutput)
    if dftest[1] <= 0.05:
        print("Conclusion:====>")
        print("Reject the null hypothesis")
        print("The data is stationary")
    else:
        print("Conclusion:====>")
        print("The null hypothesis cannot be rejected")
        print("The data is not stationary")
Augmented_Dickey_Fuller_Test_func(df["y"],"Life expectancy")
Dickey-Fuller test results for columns: Life expectancy
Test Statistic         -1.578590
p-value                 0.494339
No Lags Used            2.000000
                          ...   
Critical Value (1%)    -3.550670
Critical Value (5%)    -2.913766
Critical Value (10%)   -2.594624
Length: 7, dtype: float64
Conclusion:====>
The null hypothesis cannot be rejected
The data is not stationary

从结果中我们可以看到,我们得到了非平稳序列,因为 p 值大于 5%。

应用ADF检验的目的之一是了解我们的序列是否平稳,知道ADF检验的结果后,我们就可以确定下一步。对于我们的情况,从之前的结果可以看出时间序列不平稳,因此我们将继续进行下一步,即对时间序列进行差分。

我们将创建一份数据的副本,以便研究查找时间序列的平稳性。

创建时间序列副本后,我们将对时间序列进行差分,然后使用增广迪基-福勒检验来研究我们的时间序列是否平稳。

df1=df.copy()
df1['y_diff'] = df['y'].diff()
df1.dropna(inplace=True)
df1.head()
dsyunique_idy_diff
11961-01-0169.76024410.636341
21962-01-0169.1497561-0.610488
31963-01-0169.24804910.098293
41964-01-0170.31170711.063659
51965-01-0170.1717071-0.140000

我们再次应用迪基-福勒检验,看看我们的时间序列是否已经平稳。

Augmented_Dickey_Fuller_Test_func(df1["y_diff"],"Life expectancy")
Dickey-Fuller test results for columns: Life expectancy
Test Statistic         -8.510100e+00
p-value                 1.173776e-13
No Lags Used            1.000000e+00
                            ...     
Critical Value (1%)    -3.550670e+00
Critical Value (5%)    -2.913766e+00
Critical Value (10%)   -2.594624e+00
Length: 7, dtype: float64
Conclusion:====>
Reject the null hypothesis
The data is stationary

从之前的结果中我们可以观察到,现在我们的时间序列是平稳的了,p 值小于 5%。

现在我们的时间序列是平稳的了,也就是说,我们只差分了 1 次,因此,使模型平稳所需的差分阶数 d=1d=1

from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
import matplotlib.pyplot as plt


fig, axes = plt.subplots(2, 2, )
axes[0, 0].plot(df1["y"]); axes[0, 0].set_title('Original Series')
plot_acf(df1["y"], ax=axes[0, 1],lags=20)

axes[1, 0].plot(df1["y"].diff()); axes[1, 0].set_title('1st Order Differencing')
plot_acf(df1["y"].diff().dropna(), ax=axes[1, 1],lags=20)


plt.show()

  • 对于上述数据,我们可以看到时间序列通过一次差分达到了平稳。

如何找到AR项的阶数 (p)

  • 下一步是确定模型是否需要任何AR项。我们将通过检查偏自相关 (PACF) 图来找出所需的AR项数量。

  • 偏自相关可以想象为序列与其滞后项之间的相关性,在排除中间滞后项的贡献后。因此,PACF 某种程度上表达了滞后项与序列之间的纯粹相关性。通过这种方式,我们将知道AR项中是否需要该滞后项。

  • 序列的滞后 k 的偏自相关是该滞后项在 YY 的自回归方程中的系数。

Yt=α0+α1Yt1+α2Yt2+α3Yt3Yt = \alpha0 + \alpha1 Y{t-1} + \alpha2 Y{t-2} + \alpha3 Y{t-3}

  • 也就是说,假设如果 YtY_t 是当前序列,并且 Yt1Y_{t-1}YY 的滞后 1,那么滞后 3 (Yt3)(Y_{t-3}) 的偏自相关是上述方程中 Yt3Y_{t-3} 的系数 α3\alpha_3

  • 现在,我们应该找到AR项的数量。平稳化序列中的任何自相关都可以通过添加足够的AR项来修正。因此,我们最初将AR项的阶数设为 PACF 图中超过显著性界限的滞后项数量。

fig, axes = plt.subplots(1, 2)
axes[0].plot(df1["y"].diff()); axes[0].set_title('1st Differencing')
axes[1].set(ylim=(0,5))
plot_pacf(df1["y"].diff().dropna(), ax=axes[1],lags=20)

plt.show()

  • 我们可以看到 PACF 滞后 1 非常显著,因为它远高于显著性线。所以我们将 p 的值设为 1。

如何找到MA项的阶数 (q)

  • 就像我们查看 PACF 图来确定 AR 项数量一样,我们将查看 ACF 图来确定 MA 项数量。MA 项在技术上是滞后预测的误差。

  • ACF 告诉我们需要多少个 MA 项来消除平稳化序列中的任何自相关。

  • 让我们看看差分后序列的自相关图。

from statsmodels.graphics.tsaplots import plot_acf

fig, axes = plt.subplots(1, 2)
axes[0].plot(df1["y"].diff()); axes[0].set_title('1st Differencing')
axes[1].set(ylim=(0,1.2))
plot_acf(df["y"].diff().dropna(), ax=axes[1], lags=20)

plt.show()

  • 我们可以看到有几个滞后项远高于显著性线。所以我们将 q 设为 1。如果有疑问,我们将选择能够充分解释 Y 的更简单的模型。

如何处理时间序列轻微欠差分或过度差分的情况

  • 时间序列可能存在轻微欠差分的情况。再差分一次可能会导致轻微过度差分。

  • 如果序列轻微欠差分,通常可以通过添加一个或多个额外的 AR 项来弥补。同样,如果序列轻微过度差分,我们将尝试添加一个额外的 MA 项。

使用 StatsForecast 实现 ARIMA

现在,我们已经确定了 p、d 和 q 的值。我们已具备拟合 ARIMA 模型所需的一切。我们将使用 statsforecast 包中的 ARIMA() 实现。

找到的参数是:* 自回归模型参数 p 为 p=1p=1 * 移动平均模型参数 q 为 q=1q=1 * 以及使模型平稳所需的差分阶数 d 为 d=1d=1

因此,我们将要测试的模型是 ARIMA(1,1,1) 模型。

from statsforecast import StatsForecast
from statsforecast.models import ARIMA

实例化模型

sf = StatsForecast(models=[ARIMA(order=(1, 1, 1))], freq='YS')

拟合模型

sf.fit(df)
StatsForecast(models=[ARIMA])

进行预测

y_hat = sf.predict(h=6)
y_hat
unique_iddsARIMA
012020-01-0183.206903
112021-01-0183.203508
212022-01-0183.204742
312023-01-0183.204293
412024-01-0183.204456
512025-01-0183.204397

我们可以通过添加置信区间来进行预测,例如 95% 的置信区间。

y_hat2 = sf.predict(h=6, level=[95])
y_hat2
unique_iddsARIMAARIMA-lo-95ARIMA-hi-95
012020-01-0183.20690382.41233684.001469
112021-01-0183.20350882.09462584.312391
212022-01-0183.20474281.84834484.561139
312023-01-0183.20429381.64043084.768156
412024-01-0183.20445681.45714584.951767
512025-01-0183.20439781.29129785.117497

预测方法

内存高效的预测。

此方法避免了对象存储带来的内存负担。它类似于 fit_predict,但不存储信息。它假定您预先知道预测范围。

Y_hat_df = sf.forecast(df=df, h=6, level=[95])
Y_hat_df
unique_iddsARIMAARIMA-lo-95ARIMA-hi-95
012020-01-0183.20690382.41233684.001469
112021-01-0183.20350882.09462584.312391
212022-01-0183.20474281.84834484.561139
312023-01-0183.20429381.64043084.768156
412024-01-0183.20445681.45714584.951767
512025-01-0183.20439781.29129785.117497

生成预测后,我们可以进行可视化以查看我们模型生成的行为。

sf.plot(df, Y_hat_df, level=[95])

模型评估

常用的预测评估指标包括

  1. 平均绝对百分比误差 (MAPE)
  2. 平均误差 (ME)
  3. 平均绝对误差 (MAE)
  4. 平均百分比误差 (MPE)
  5. 均方根误差 (RMSE)
  6. 实际值与预测值之间的相关性 (corr)
Y_train_df = df[df.ds<='2013-01-01'] 
Y_test_df = df[df.ds>'2013-01-01'] 

Y_train_df.shape, Y_test_df.shape
((54, 3), (6, 3))
Y_hat_df = sf.forecast(df=Y_train_df, h=len(Y_test_df))
import utilsforecast.losses as ufl
from utilsforecast.evaluation import evaluate
evaluate(
    Y_test_df.merge(Y_hat_df),
    metrics=[ufl.mse, ufl.mae, ufl.rmse, ufl.mape],
)
unique_id指标ARIMA
01mse0.184000
11mae0.397932
21rmse0.428952
31mape0.004785

参考文献

  1. Nixtla-Arima
  2. Rob J. Hyndman 和 George Athanasopoulos (2018)。《预测:原理与实践 (第3版)》.