长期预测与变压器模型

关于如何训练和预测变压器模型的教程。

Transformer模型最初是为自然语言处理应用而提出的,近年来在时间序列预测领域得到了越来越广泛的应用。这些模型的变革力量在于其新颖的架构,严重依赖自注意力机制,这帮助模型关注输入序列的不同部分以进行预测,同时捕捉数据中的长期依赖性。在时间序列预测的背景下,Transformer模型利用这一自注意力机制来识别时间序列中不同周期的相关信息,使其在复杂和噪声序列的未来值预测中表现得极为有效。

长时间预测包括预测大量时间戳。这是一项具有挑战性的任务,因为预测的波动性计算复杂性。为了应对这个问题,最近的研究提出了一系列基于Transformer的模型。

Neuralforecast库包含以下流行的最近模型的实现:Informer(Zhou, H. et al. 2021)、Autoformer(Wu et al. 2021)、FEDformer(Zhou, T. et al. 2022)和PatchTST(Nie et al. 2023)。

我们对所有这些模型的实现都是单变量的,这意味着只使用每个特征的自回归值进行预测。我们观察到这些单变量模型比其多变量对应模型更准确且更快速

在这个笔记本中,我们将展示如何: * 加载学术文献中使用的ETTm2基准数据集。 * 训练模型 * 预测测试集

在本笔记本中取得的结果超越了各自原始论文中自报的原始结果,且计算成本的比例较小。此外,所有模型均使用默认推荐参数进行训练,使用我们的auto模型和自动超参数选择可以进一步改善结果。

您可以使用GPU在Google Colab中运行这些实验。

在Colab中打开

1. 安装库

%%capture
!pip install neuralforecast datasetsforecast

2. 加载ETTm2数据

LongHorizon类将自动下载完整的ETTm2数据集并进行处理。

它返回三个DataFrame:Y_df包含目标变量的值,X_df包含外生的日历特征,S_df包含每个时间序列的静态特征(ETTm2没有静态特征)。在这个例子中,我们只会使用Y_df

如果你想使用自己的数据,只需替换Y_df。确保使用长格式,并且与我们的数据集具有相似的结构。

import pandas as pd

from datasetsforecast.long_horizon import LongHorizon
# 将此更改为自己的数据以尝试模型
Y_df, _, _ = LongHorizon.load(directory='./', group='ETTm2')
Y_df['ds'] = pd.to_datetime(Y_df['ds'])

n_time = len(Y_df.ds.unique())
val_size = int(.2 * n_time)
test_size = int(.2 * n_time)

Y_df.groupby('unique_id').head(2)
unique_id ds y
0 HUFL 2016-07-01 00:00:00 -0.041413
1 HUFL 2016-07-01 00:15:00 -0.185467
57600 HULL 2016-07-01 00:00:00 0.040104
57601 HULL 2016-07-01 00:15:00 -0.214450
115200 LUFL 2016-07-01 00:00:00 0.695804
115201 LUFL 2016-07-01 00:15:00 0.434685
172800 LULL 2016-07-01 00:00:00 0.434430
172801 LULL 2016-07-01 00:15:00 0.428168
230400 MUFL 2016-07-01 00:00:00 -0.599211
230401 MUFL 2016-07-01 00:15:00 -0.658068
288000 MULL 2016-07-01 00:00:00 -0.393536
288001 MULL 2016-07-01 00:15:00 -0.659338
345600 OT 2016-07-01 00:00:00 1.018032
345601 OT 2016-07-01 00:15:00 0.980124

3. 训练模型

我们将使用 cross_validation 方法来训练模型,该方法允许用户自动模拟多个历史预测(在测试集上)。

cross_validation 方法将使用验证集进行超参数选择和早期停止,然后为测试集生成预测。

首先,实例化 models 列表中的每个模型,指定 horizoninput_size 和训练迭代次数。

(注:由于训练时间异常长,FEDformer 模型被排除在外。)

%%capture
from neuralforecast.core import NeuralForecast
from neuralforecast.models import Informer, Autoformer, FEDformer, PatchTST
INFO:torch.distributed.nn.jit.instantiator:Created a temporary directory at /tmp/tmpopb2vyyt
INFO:torch.distributed.nn.jit.instantiator:Writing /tmp/tmpopb2vyyt/_remote_module_non_scriptable.py
%%capture
horizon = 96 # 24小时 = 4 * 15分钟。
models = [Informer(h=horizon,                 # 预测时间范围
                input_size=horizon,           # 输入大小
                max_steps=1000,               # 训练迭代次数
                val_check_steps=100,          # 每100步计算一次验证损失
                early_stop_patience_steps=3), # 如果验证损失没有改善,请停止训练。
          Autoformer(h=horizon,
                input_size=horizon,
                max_steps=1000,
                val_check_steps=100,
                early_stop_patience_steps=3),
          PatchTST(h=horizon,
                input_size=horizon,
                max_steps=1000,
                val_check_steps=100,
                early_stop_patience_steps=3),
         ]
INFO:lightning_fabric.utilities.seed:Global seed set to 1
INFO:lightning_fabric.utilities.seed:Global seed set to 1
INFO:lightning_fabric.utilities.seed:Global seed set to 1
Tip

查看我们的auto模型以进行自动超参数优化。

实例化一个 NeuralForecast 对象,需提供以下必需参数:

  • models: 一个模型列表。

  • freq: 一个字符串,指示数据的频率。(请参见 pandas 的可用频率.)

其次,使用 cross_validation 方法,指定数据集 (Y_df)、验证大小和测试大小。

%%capture
nf = NeuralForecast(
    models=models,
    freq='15min')

Y_hat_df = nf.cross_validation(df=Y_df,
                               val_size=val_size,
                               test_size=test_size,
                               n_windows=None)

cross_validation 方法将返回每个模型在测试集上的预测结果。

Y_hat_df.head()
unique_id ds cutoff Informer Autoformer PatchTST y
0 HUFL 2017-10-24 00:00:00 2017-10-23 23:45:00 -1.055062 -0.861487 -0.860189 -0.977673
1 HUFL 2017-10-24 00:15:00 2017-10-23 23:45:00 -1.021247 -0.873399 -0.865730 -0.865620
2 HUFL 2017-10-24 00:30:00 2017-10-23 23:45:00 -1.057297 -0.900345 -0.944296 -0.961624
3 HUFL 2017-10-24 00:45:00 2017-10-23 23:45:00 -0.886652 -0.867466 -0.974849 -1.049700
4 HUFL 2017-10-24 01:00:00 2017-10-23 23:45:00 -1.000431 -0.887454 -1.008530 -0.953600

4. 评估结果

接下来,我们为所有模型绘制 OT 变量在测试集上的预测。

import matplotlib.pyplot as plt
Y_plot = Y_hat_df[Y_hat_df['unique_id']=='OT'] # OT数据集
cutoffs = Y_hat_df['cutoff'].unique()[::horizon]
Y_plot = Y_plot[Y_hat_df['cutoff'].isin(cutoffs)]

plt.figure(figsize=(20,5))
plt.plot(Y_plot['ds'], Y_plot['y'], label='True')
plt.plot(Y_plot['ds'], Y_plot['Informer'], label='Informer')
plt.plot(Y_plot['ds'], Y_plot['Autoformer'], label='Autoformer')
plt.plot(Y_plot['ds'], Y_plot['PatchTST'], label='PatchTST')
plt.xlabel('Datestamp')
plt.ylabel('OT')
plt.grid()
plt.legend()

最后,我们使用平均绝对误差(MAE)计算测试误差:

\(\qquad MAE = \frac{1}{Windows * Horizon} \sum_{\tau} |y_{\tau} - \hat{y}_{\tau}| \qquad\)

from neuralforecast.losses.numpy import mae
mae_informer = mae(Y_hat_df['y'], Y_hat_df['Informer'])
mae_autoformer = mae(Y_hat_df['y'], Y_hat_df['Autoformer'])
mae_patchtst = mae(Y_hat_df['y'], Y_hat_df['PatchTST'])

print(f'Informer: {mae_informer:.3f}')
print(f'Autoformer: {mae_autoformer:.3f}')
print(f'PatchTST: {mae_patchtst:.3f}')
Informer: 0.339
Autoformer: 0.316
PatchTST: 0.251

为参考,我们可以比较各自论文中自我报告的性能。

预测期 PatchTST AutoFormer Informer ARIMA
96 0.256 0.339 0.453 0.301
192 0.296 0.340 0.563 0.345
336 0.329 0.372 0.887 0.386
720 0.385 0.419 1.388 0.445

接下来的步骤

我们提出了一种用于长远预测的替代模型 NHITS,基于前馈网络(Challu et al. 2023)。它在性能上可与 PatchTST 媲美,同时计算成本却低得多。NHITS 的教程可以在 这里 找到。

参考文献

Zhou, H., Zhang, S., Peng, J., Zhang, S., Li, J., Xiong, H., & Zhang, W. (2021年5月)。Informer: 超越高效变压器的长序列时间序列预测。在人工智能AAAI会议论文集中(第35卷,第12期,页面11106-11115)

Wu, H., Xu, J., Wang, J., & Long, M. (2021)。Autoformer: 带有自动相关的分解变压器用于长期序列预测。神经信息处理系统进展,34,22419-22430。

Zhou, T., Ma, Z., Wen, Q., Wang, X., Sun, L., & Jin, R. (2022年6月)。Fedformer: 频率增强的分解变压器用于长期序列预测。在国际机器学习会议上(页面27268-27286)。PMLR。

Nie, Y., Nguyen, N. H., Sinthong, P., & Kalagnanam, J. (2022)。一个时间序列值64个词:使用变压器进行长期预测。

Cristian Challu, Kin G. Olivares, Boris N. Oreshkin, Federico Garza, Max Mergenthaler-Canseco, Artur Dubrawski (2021)。NHITS: 用于时间序列预测的神经分层插值。已被AAAI 2023接收。

Give us a ⭐ on Github