迁移学习是指在大型数据集上预训练一个灵活的模型,然后几乎无需或只需少量额外训练即可将其用于其他数据的过程。它是机器学习 🧠 中最杰出的 🚀 成就之一,具有许多实际应用。

对于时间序列预测,这项技术可以让你获得闪电般快速的预测 ⚡,绕过精度和速度之间的权衡(对于类似的精度,比我们已有的快速 autoARIMA 快 30 多倍)。

本 notebook 演示了如何生成预训练模型并将其存储在检查点中,以便能够预测模型从未见过的新时间序列。

目录
1. 安装 NeuralForecast/DatasetsForecast
2. 加载 M4 数据
3. 实例化 NeuralForecast 核心,拟合并保存
4. 加载预训练模型并对 AirPassengers 进行预测
5. 评估结果

你可以使用 Google Colab 通过 GPU 运行这些实验。

1. 安装库

!pip install datasetsforecast neuralforecast
import logging

import numpy as np
import pandas as pd
import torch
from datasetsforecast.m4 import M4
from neuralforecast.core import NeuralForecast
from neuralforecast.models import NHITS
from neuralforecast.utils import AirPassengersDF
from utilsforecast.losses import mae
from utilsforecast.plotting import plot_series
logging.getLogger("pytorch_lightning").setLevel(logging.WARNING)

如果可用,此示例将自动在 GPU 上运行。确保 cuda 可用。(如果您需要将此投入生产的帮助,请发送电子邮件给我们或加入我们的社区,我们还提供完全托管的解决方案)

torch.cuda.is_available()
True

2. 加载 M4 数据

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

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

如果您想使用自己的数据,只需替换 Y_df。请务必使用长格式,并且结构与我们的数据集相似。

Y_df, _, _ = M4.load(directory='./', group='Monthly', cache=True)
Y_df['ds'] = pd.to_datetime(Y_df['ds'])
Y_df
unique_iddsy
0M11970-01-01 00:00:00.0000000018000.0
1M11970-01-01 00:00:00.0000000028350.0
2M11970-01-01 00:00:00.0000000038570.0
3M11970-01-01 00:00:00.0000000047700.0
4M11970-01-01 00:00:00.0000000057080.0
11246406M99991970-01-01 00:00:00.0000000834200.0
11246407M99991970-01-01 00:00:00.0000000844300.0
11246408M99991970-01-01 00:00:00.0000000853800.0
11246409M99991970-01-01 00:00:00.0000000864400.0
11246410M99991970-01-01 00:00:00.0000000874300.0

3. 模型训练和保存

使用 NeuralForecast.fit 方法,您可以训练一组模型以适应您的数据集。您只需定义模型的 input_sizehorizoninput_size 是模型将用于学习预测未来 h 步的历史观测值(滞后项)的数量。此外,您还可以修改模型的超参数以获得更好的精度。

horizon = 12
stacks = 3
models = [NHITS(input_size=5 * horizon,
                h=horizon,
                max_steps=100,
                stack_types = stacks*['identity'],
                n_blocks = stacks*[1],
                mlp_units = [[256,256] for _ in range(stacks)],
                n_pool_kernel_size = stacks*[1],
                batch_size = 32,
                scaler_type='standard',
                n_freq_downsample=[12,4,1],
                enable_progress_bar=False,
                interpolation_mode="nearest",
               )]
nf = NeuralForecast(models=models, freq='ME')
nf.fit(df=Y_df)
INFO:lightning_fabric.utilities.seed:Seed set to 1

使用 core.NeuralForecast.save 方法保存模型。此方法使用 PytorchLightning 的 save_checkpoint 函数。我们将 save_dataset 设置为 False 以仅保存模型。

nf.save(path='./results/transfer/', model_index=None, overwrite=True, save_dataset=False)

4. 将 M4 迁移到 AirPassengers

我们使用 core.NeuralForecast.load 方法加载存储的模型,并使用 core.NeuralForecast.predict 函数预测 AirPassenger

fcst2 = NeuralForecast.load(path='./results/transfer/')
c:\Nixtla\Repositories\neuralforecast\neuralforecast\common\_base_model.py:133: UserWarning: NHITS is a univariate model. Parameter n_series is ignored.
  warnings.warn(
INFO:lightning_fabric.utilities.seed:Seed set to 1
# We define the train df. 
Y_df = AirPassengersDF.copy()
mean = Y_df[Y_df.ds<='1959-12-31']['y'].mean()
std = Y_df[Y_df.ds<='1959-12-31']['y'].std()

Y_train_df = Y_df[Y_df.ds<='1959-12-31'] # 132 train
Y_test_df = Y_df[Y_df.ds>'1959-12-31']   # 12 test
Y_hat_df = fcst2.predict(df=Y_train_df)
Y_hat_df.head()
unique_iddsNHITS
01.01960-01-31422.038757
11.01960-02-29424.678040
21.01960-03-31439.538879
31.01960-04-30447.967072
41.01960-05-31470.603333
plot_series(Y_train_df, Y_hat_df)

5. 评估结果

我们使用平均绝对误差 (mae) 评估预训练模型的预测结果。

MAE=1Horizonτyτy^τ \qquad MAE = \frac{1}{Horizon} \sum_{\tau} |y_{\tau} - \hat{y}_{\tau}|\qquad
fcst_mae = mae(Y_test_df.merge(Y_hat_df), models=['NHITS'])['NHITS'].item()
print(f'NHITS     MAE: {fcst_mae:.3f}')
print('ETS       MAE: 16.222')
print('AutoARIMA MAE: 18.551')
NHITS     MAE: 17.245
ETS       MAE: 16.222
AutoARIMA MAE: 18.551