%%capture
!pip install neuralforecast datasetsforecast长期预测与变压器模型
关于如何训练和预测变压器模型的教程。
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中运行这些实验。
1. 安装库
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 列表中的每个模型,指定 horizon、input_size 和训练迭代次数。
(注:由于训练时间异常长,FEDformer 模型被排除在外。)
%%capture
from neuralforecast.core import NeuralForecast
from neuralforecast.models import Informer, Autoformer, FEDformer, PatchTSTINFO: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
查看我们的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 pltY_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 maemae_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 的教程可以在 这里 找到。
参考文献
Nie, Y., Nguyen, N. H., Sinthong, P., & Kalagnanam, J. (2022)。一个时间序列值64个词:使用变压器进行长期预测。
Give us a ⭐ on Github