多元 时间序列预测中,我们使用所有时间序列的信息联合生成所有时间序列的预测。相比之下,在 单变量 时间序列预测中,我们只考虑每个单独时间序列的信息,并单独生成每个时间序列的预测。因此,多元时间序列预测方法使用更多信息来生成每个预测,从而应该能够提供更好的预测结果。然而,多元时间序列预测方法也随着时间序列数量的增加而扩展,这意味着这些方法通常不太适合大规模问题(即预测许多许多时间序列)。

在本 Notebook 中,我们将演示最先进的多元时间序列预测架构 TSMixer / TSMixerx 与单变量时间序列预测方法 (NHITS) 和简单的基于 MLP 的多元方法 (MLPMultivariate) 相比的性能。

我们将展示如何: * 加载学术文献中使用的 ETTm2 基准数据集。 * 训练 TSMixerTSMixerxMLPMultivariate 模型 * 预测测试集 * 优化超参数

您可以使用 Google Colab 上的 GPU 运行这些实验。

1. 安装库

!pip install neuralforecast datasetsforecast

2. 加载 ETTm2 数据

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

它返回三个 Dataframe:Y_df 包含目标变量的值,X_df 包含外部日历特征,S_df 包含每个时间序列的静态特征(ETTm2 没有)。在本示例中,我们将使用 Y_dfX_df

TSMixerx 中,我们可以利用 X_df 中包含的额外外部特征。在 TSMixer 中,*不*支持外部特征。因此,如果您想使用外部特征,应该使用 TSMixerx

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

import pandas as pd

from datasetsforecast.long_horizon import LongHorizon
# Change this to your own data to try the model
Y_df, X_df, _ = LongHorizon.load(directory='./', group='ETTm2')
Y_df['ds'] = pd.to_datetime(Y_df['ds'])

# X_df contains the exogenous features, which we add to Y_df
X_df['ds'] = pd.to_datetime(X_df['ds'])
Y_df = Y_df.merge(X_df, on=['unique_id', 'ds'], how='left')

# We make validation and test splits
n_time = len(Y_df.ds.unique())
val_size = int(.2 * n_time)
test_size = int(.2 * n_time)
Y_df
unique_iddsyex_1ex_2ex_3ex_4
0HUFL2016-07-01 00:00:00-0.041413-0.5000000.166667-0.500000-0.001370
1HUFL2016-07-01 00:15:00-0.185467-0.5000000.166667-0.500000-0.001370
2HUFL2016-07-01 00:30:00-0.257495-0.5000000.166667-0.500000-0.001370
3HUFL2016-07-01 00:45:00-0.577510-0.5000000.166667-0.500000-0.001370
4HUFL2016-07-01 01:00:00-0.385501-0.4565220.166667-0.500000-0.001370
403195OT2018-02-20 22:45:00-1.5813250.456522-0.3333330.133333-0.363014
403196OT2018-02-20 23:00:00-1.5813250.500000-0.3333330.133333-0.363014
403197OT2018-02-20 23:15:00-1.5813250.500000-0.3333330.133333-0.363014
403198OT2018-02-20 23:30:00-1.5623280.500000-0.3333330.133333-0.363014
403199OT2018-02-20 23:45:00-1.5623280.500000-0.3333330.133333-0.363014

3. 训练模型

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

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

首先,实例化 models 列表中的每个模型,指定 horizoninput_size 和训练迭代次数。在本 Notebook 中,我们将与单变量 NHITS 模型和多元 MLPMultivariate 模型进行比较。

import logging

import torch
from neuralforecast.core import NeuralForecast
from neuralforecast.models import TSMixer, TSMixerx, NHITS, MLPMultivariate
from neuralforecast.losses.pytorch import MAE
logging.getLogger('pytorch_lightning').setLevel(logging.ERROR)
torch.set_float32_matmul_precision('high')
horizon = 96
input_size = 512
models = [
          TSMixer(h=horizon,
                input_size=input_size,
                n_series=7,
                max_steps=1000,
                val_check_steps=100,
                early_stop_patience_steps=5,
                scaler_type='identity',
                valid_loss=MAE(),
                random_seed=12345678,
                ),  
          TSMixerx(h=horizon,
                input_size=input_size,
                n_series=7,
                max_steps=1000,
                val_check_steps=100,
                early_stop_patience_steps=5,
                scaler_type='identity',
                dropout=0.7,
                valid_loss=MAE(),
                random_seed=12345678,
                futr_exog_list=['ex_1', 'ex_2', 'ex_3', 'ex_4'],
                ),
          MLPMultivariate(h=horizon,
                input_size=input_size,
                n_series=7,
                max_steps=1000,
                val_check_steps=100,
                early_stop_patience_steps=5,
                scaler_type='standard',
                hidden_size=256,
                valid_loss=MAE(),
                random_seed=12345678,
                ),                                             
           NHITS(h=horizon,
                input_size=horizon,
                max_steps=1000,
                val_check_steps=100,
                early_stop_patience_steps=5,
                scaler_type='robust',
                valid_loss=MAE(),
                random_seed=12345678,
                ),                                                                       
         ]

提示

请查看我们的 auto 模型以进行自动超参数优化,并参阅本教程末尾的超参数调优示例。

使用以下必需参数实例化一个 NeuralForecast 对象

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

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 方法将返回测试集上每个模型的预测结果。

4. 评估结果

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

from utilsforecast.plotting import plot_series
cutoffs = Y_hat_df['cutoff'].unique()[::horizon]
Y_plot = Y_hat_df[Y_hat_df['cutoff'].isin(cutoffs)].drop(columns='cutoff')
plot_series(forecasts_df=Y_plot, ids=['OT'])

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

MAE=1WindowsHorizonτyτy^τ\qquad MAE = \frac{1}{Windows * Horizon} \sum_{\tau} |y_{\tau} - \hat{y}_{\tau}| \qquadMSE=1WindowsHorizonτ(yτy^τ)2\qquad MSE = \frac{1}{Windows * Horizon} \sum_{\tau} (y_{\tau} - \hat{y}_{\tau})^{2} \qquad

from utilsforecast.evaluation import evaluate
from utilsforecast.losses import mae, mse
evaluate(Y_hat_df.drop(columns='cutoff'), metrics=[mae, mse], agg_fn='mean')
指标TSMixerTSMixerxMLPMultivariateNHITS
0mae0.2454350.2497270.2635790.251008
1mse0.1625660.1630980.1765940.178864

作为参考,我们可以将性能与论文中自行报告的性能进行比较。我们发现 TSMixer 提供了比单变量方法 NHITS 更好的结果。此外,我们实现的 TSMixer 与原始论文的结果非常接近。最后,使用 X_df Dataframe 中包含的额外外部变量似乎没有多大益处,因为 TSMixerx 的性能不如 TSMixer,尤其是在较长的预测周期上。另请注意,与其它方法相比,MLPMultivariate 的性能明显较差,考虑到其相对简单性,这在一定程度上是可以预料的。

平均绝对误差 (MAE)

预测周期TSMixer
(本 Notebook)
TSMixer
(论文)
TSMixerx
(本 Notebook)
NHITS
(本 Notebook)
NHITS
(论文)
MLPMultivariate
(本 Notebook)
960.2450.2520.2500.2510.2510.263
1920.2880.2900.3000.2910.3050.361
3360.3230.3240.3800.3440.3460.390
7200.3770.4220.4640.4170.4130.608

均方误差 (MSE)

预测周期TSMixer
(本 Notebook)
TSMixer
(论文)
TSMixerx
(本 Notebook)
NHITS
(本 Notebook)
NHITS
(论文)
MLPMultivariate
(本 Notebook)
960.1630.1630.1630.1790.1790.177
1920.2200.2160.2310.2390.2450.330
3360.2720.2680.3610.3110.2950.376
7200.3560.4200.4930.4510.4013.421

请注意,对于上表,我们在所有预测周期中对所有方法使用相同的超参数,而原始论文会为每个预测周期调整超参数。

5. 调优超参数

AutoTSMixer / AutoTSMixerx 类将使用 Tune 库自动执行超参数调优,探索用户定义或默认的搜索空间。模型根据在验证集上的误差进行选择,然后存储最佳模型并在推理时使用。

AutoTSMixer.default_config / AutoTSMixerx.default_config 属性包含建议的超参数空间。在这里,我们根据论文的超参数指定了不同的搜索空间。您可以随意调整此空间。

在本示例中,我们将优化 horizon = 96 的超参数。

from ray import tune
from ray.tune.search.hyperopt import HyperOptSearch
from neuralforecast.auto import AutoTSMixer, AutoTSMixerx
horizon = 96 # 24hrs = 4 * 15 min.

tsmixer_config = {
       "input_size": input_size,                                                 # Size of input window
       "max_steps": tune.choice([500, 1000, 2000]),                              # Number of training iterations
       "val_check_steps": 100,                                                   # Compute validation every x steps
       "early_stop_patience_steps": 5,                                           # Early stopping steps
       "learning_rate": tune.loguniform(1e-4, 1e-2),                             # Initial Learning rate
       "n_block": tune.choice([1, 2, 4, 6, 8]),                                  # Number of mixing layers
       "dropout": tune.uniform(0.0, 0.99),                                       # Dropout
       "ff_dim": tune.choice([32, 64, 128]),                                     # Dimension of the feature linear layer
       "scaler_type": 'identity',       
    }

tsmixerx_config = tsmixer_config.copy()
tsmixerx_config['futr_exog_list'] = ['ex_1', 'ex_2', 'ex_3', 'ex_4']

要实例化 AutoTSMixerAutoTSMixerx,您需要定义

  • h:预测周期
  • n_series:多元时间序列问题中的时间序列数量。

此外,我们定义以下参数(如果未给出这些参数,AutoTSMixer/AutoTSMixerx 类将使用预定义值):* loss:训练损失。使用 DistributionLoss 生成概率预测。* config:超参数搜索空间。如果为 NoneAutoTSMixer 类将使用预定义的建议超参数空间。* num_samples:探索的配置数量。在本例中,我们仅使用有限的 10 个。* search_alg:用于在超参数空间中选择参数值的搜索算法类型。* backend:用于超参数优化搜索的后端,可以是 rayoptuna。* valid_loss:优化过程中用于验证集的损失。

model = AutoTSMixer(h=horizon,
                    n_series=7,
                    loss=MAE(),
                    config=tsmixer_config,
                    num_samples=10,
                    search_alg=HyperOptSearch(),
                    backend='ray',
                    valid_loss=MAE())

modelx = AutoTSMixerx(h=horizon,
                    n_series=7,
                    loss=MAE(),
                    config=tsmixerx_config,
                    num_samples=10,
                    search_alg=HyperOptSearch(),
                    backend='ray',
                    valid_loss=MAE())

现在,通过实例化一个具有以下必需参数的 NeuralForecast 对象来拟合模型

cross_validation 方法允许您模拟多个历史预测,通过用 fitpredict 方法替换 for 循环来大大简化管道。

对于时间序列数据,交叉验证是通过在历史数据上定义一个滑动窗口并预测其后面的时期来完成的。这种形式的交叉验证使我们能够在更广泛的时间范围内更好地估计模型的预测能力,同时保持训练集中的数据连续,这是我们的模型所必需的。

cross_validation 方法将使用验证集进行超参数选择,然后生成测试集的预测。

nf = NeuralForecast(models=[model, modelx], freq='15min')
Y_hat_df = nf.cross_validation(df=Y_df, val_size=val_size,
                               test_size=test_size, n_windows=None)

6. 评估结果

AutoTSMixer/AutoTSMixerx 类包含一个 results 属性,用于存储探索的每个配置的信息。它包含验证损失和最佳验证超参数。我们在上一步中获得的 Y_hat_df 结果 Dataframe 是基于超参数搜索的最佳配置。对于 AutoTSMixer,最佳配置是

nf.models[0].results.get_best_result().config
{'input_size': 512,
 'max_steps': 2000,
 'val_check_steps': 100,
 'early_stop_patience_steps': 5,
 'learning_rate': 0.00034884229033995355,
 'n_block': 4,
 'dropout': 0.7592667651473878,
 'ff_dim': 128,
 'scaler_type': 'identity',
 'n_series': 7,
 'h': 96,
 'loss': MAE(),
 'valid_loss': MAE()}

对于 AutoTSMixerx

nf.models[1].results.get_best_result().config
{'input_size': 512,
 'max_steps': 2000,
 'val_check_steps': 100,
 'early_stop_patience_steps': 5,
 'learning_rate': 0.00019039338576148522,
 'n_block': 6,
 'dropout': 0.5902743834953548,
 'ff_dim': 128,
 'scaler_type': 'identity',
 'futr_exog_list': ('ex_1', 'ex_2', 'ex_3', 'ex_4'),
 'n_series': 7,
 'h': 96,
 'loss': MAE(),
 'valid_loss': MAE()}

我们计算最佳配置在这两个感兴趣指标上的测试误差

MAE=1WindowsHorizonτyτy^τ\qquad MAE = \frac{1}{Windows * Horizon} \sum_{\tau} |y_{\tau} - \hat{y}_{\tau}| \qquadMSE=1WindowsHorizonτ(yτy^τ)2\qquad MSE = \frac{1}{Windows * Horizon} \sum_{\tau} (y_{\tau} - \hat{y}_{\tau})^{2} \qquad

evaluate(Y_hat_df.drop(columns='cutoff'), metrics=[mae, mse], agg_fn='mean')
指标AutoTSMixerAutoTSMixerx
0mae0.2437490.251972
1mse0.1622120.164347

我们可以将优化设置的错误指标与之前使用默认超参数的设置进行比较。在本例中,对于预测周期为 96,TSMixerMAE 上取得了略微改进的结果。有趣的是,与默认设置相比,TSMixerx 没有得到改进。对于此数据集,在预测周期为 96 时,使用 TSMixerx 架构中的外部特征似乎价值有限。

指标TSMixer
(优化)
TSMixer
(默认)
TSMixer
(论文)
TSMixerx
(优化)
TSMixerx
(默认)
MAE0.2440.2450.2520.2520.250
MSE0.1620.1630.1630.1640.163

请注意,我们仅评估了 10 种超参数配置(num_samples=10),这可能表明通过探索更多超参数配置可以进一步提高预测性能。

参考文献

Chen, Si-An, Chun-Liang Li, Nate Yoder, Sercan O. Arik, and Tomas Pfister (2023). “TSMixer: 一种用于时间序列预测的全 MLP 架构。”
Cristian Challu, Kin G. Olivares, Boris N. Oreshkin, Federico Garza, Max Mergenthaler-Canseco, Artur Dubrawski (2021). NHITS: 用于时间序列预测的神经层级插值。被 AAAI 2023 接受。