在本 notebook 中,我们将演示如何使用 TimeGPT 进行预测,并探索三种提高预测准确性的常见策略。我们使用德国的小时电价数据作为示例数据集。在运行 notebook 之前,请在下面的代码片段中,使用您的 api_key 初始化 NixtlaClient 对象。

结果摘要

步骤描述MAEMAE 改进 (%)RMSERMSE 改进 (%)
0零样本 TimeGPT18.5N/A20.0N/A
1增加微调步数11.538%12.637%
2调整微调损失函数9.648%11.045%
3微调更多参数9.051%11.344%
4添加外生变量4.675%6.468%
5切换到长周期模型6.465%7.762%

首先,我们安装并导入所需的包,初始化 Nixtla 客户端,并创建一个用于计算评估指标的函数。

import numpy as np
import pandas as pd

from utilsforecast.evaluation import evaluate
from utilsforecast.plotting import plot_series
from utilsforecast.losses import mae, rmse
from nixtla import NixtlaClient
nixtla_client = NixtlaClient(
    # api_key = 'my_api_key_provided_by_nixtla'
)

1. 加载数据集

在本 notebook 中,我们使用小时电价作为示例数据集,该数据集包含 5 个时间序列,每个时间序列约有 1700 个数据点。为了演示目的,我们重点关注德国的电价系列。时间序列被分割,最后 48 步(2 天)留作测试集。

df = pd.read_csv('https://raw.githubusercontent.com/Nixtla/transfer-learning-time-series/main/datasets/electricity-short-with-ex-vars.csv')
df['ds'] = pd.to_datetime(df['ds'])
df_sub = df.query('unique_id == "DE"')
df_train = df_sub.query('ds < "2017-12-29"')
df_test = df_sub.query('ds >= "2017-12-29"')
df_train.shape, df_test.shape
((1632, 12), (48, 12))
plot_series(df_train[['unique_id','ds','y']][-200:], forecasts_df= df_test[['unique_id','ds','y']].rename(columns={'y': 'test'}))

2. 使用 TimeGPT 进行基准预测

我们使用 TimeGPT 为时间序列生成零样本预测。如图中所示,TimeGPT 很好地捕捉了总体趋势,但在建模实际数据中存在的短期波动和周期性模式方面有所不足。在测试期间,模型实现了平均绝对误差 (MAE) 18.5 和均方根误差 (RMSE) 20。此预测作为进一步比较和优化的基准。

fcst_timegpt = nixtla_client.forecast(df = df_train[['unique_id','ds','y']],
                                      h=2*24,
                                      target_col = 'y',
                                      level = [90, 95])
INFO:nixtla.nixtla_client:Validating inputs...
INFO:nixtla.nixtla_client:Inferred freq: h
INFO:nixtla.nixtla_client:Preprocessing dataframes...
INFO:nixtla.nixtla_client:Querying model metadata...
WARNING:nixtla.nixtla_client:The specified horizon "h" exceeds the model horizon, this may lead to less accurate forecasts. Please consider using a smaller horizon.
INFO:nixtla.nixtla_client:Restricting input...
INFO:nixtla.nixtla_client:Calling Forecast Endpoint...
metrics = [mae, rmse]
evaluation = evaluate(
    fcst_timegpt.merge(df_test, on=['unique_id', 'ds']),
    metrics=metrics,
    models=['TimeGPT']
)
evaluation
unique_idmetricTimeGPT
0DEmae18.519004
1DErmse20.037751
plot_series(df_sub.iloc[-150:], forecasts_df= fcst_timegpt, level = [90])

3. 提高预测准确性的方法

3a. 增加微调步数

提高预测准确性的第一种方法是增加微调步数。微调过程会调整 TimeGPT 模型中的权重,使其更好地拟合您的自定义数据。这种调整使 TimeGPT 能够更有效地学习时间序列的细微之处,从而获得更准确的预测。通过 30 个微调步数,我们观察到 MAE 降至 11.5,RMSE 降至 12.6。

fcst_finetune_df = nixtla_client.forecast(df=df_train[['unique_id', 'ds', 'y']],
                                          h=24*2,
                                          finetune_steps = 30,
                                          level=[90, 95])
INFO:nixtla.nixtla_client:Validating inputs...
INFO:nixtla.nixtla_client:Inferred freq: h
INFO:nixtla.nixtla_client:Preprocessing dataframes...
WARNING:nixtla.nixtla_client:The specified horizon "h" exceeds the model horizon, this may lead to less accurate forecasts. Please consider using a smaller horizon.
INFO:nixtla.nixtla_client:Calling Forecast Endpoint...
evaluation = evaluate(
    fcst_finetune_df.merge(df_test, on=['unique_id', 'ds']),
    metrics=metrics,
    models=['TimeGPT']
)
evaluation
unique_idmetricTimeGPT
0DEmae11.458185
1DErmse12.642999
plot_series(df_sub[-200:], forecasts_df= fcst_finetune_df, level = [90])

3b. 使用不同的损失函数进行微调

进一步降低预测误差的第二种方法是调整微调期间使用的损失函数。您可以使用 finetune_loss 参数指定自定义损失函数。通过修改损失函数,我们观察到 MAE 降至 9.6,RMSE 降至 11.0。

fcst_finetune_mae_df = nixtla_client.forecast(df=df_train[['unique_id', 'ds', 'y']],
                                          h=24*2,
                                          finetune_steps = 30,
                                          finetune_loss = 'mae',
                                          level=[90, 95])
INFO:nixtla.nixtla_client:Validating inputs...
INFO:nixtla.nixtla_client:Inferred freq: h
INFO:nixtla.nixtla_client:Preprocessing dataframes...
WARNING:nixtla.nixtla_client:The specified horizon "h" exceeds the model horizon, this may lead to less accurate forecasts. Please consider using a smaller horizon.
INFO:nixtla.nixtla_client:Calling Forecast Endpoint...
evaluation = evaluate(
    fcst_finetune_mae_df.merge(df_test, on=['unique_id', 'ds']),
    metrics=metrics,
    models=['TimeGPT']
)
evaluation
unique_idmetricTimeGPT
0DEmae9.640649
1DErmse10.956003
plot_series(df_sub[-200:], forecasts_df= fcst_finetune_mae_df, level = [90])

3c. 调整微调的参数数量

使用 finetune_depth 参数,我们可以控制微调的参数数量。默认情况下,finetune_depth=1,这意味着很少参数被微调。我们可以将其设置为 1 到 5 之间的任何值,其中 5 表示我们微调模型的所有参数。

fcst_finetune_depth_df = nixtla_client.forecast(df=df_train[['unique_id', 'ds', 'y']],
                                                h=24*2,
                                                finetune_steps = 30,
                                                finetune_depth=2,
                                                finetune_loss = 'mae',
                                                level=[90, 95])
INFO:nixtla.nixtla_client:Validating inputs...
INFO:nixtla.nixtla_client:Inferred freq: h
INFO:nixtla.nixtla_client:Preprocessing dataframes...
WARNING:nixtla.nixtla_client:The specified horizon "h" exceeds the model horizon, this may lead to less accurate forecasts. Please consider using a smaller horizon.
INFO:nixtla.nixtla_client:Calling Forecast Endpoint...
evaluation = evaluate(
    fcst_finetune_depth_df.merge(df_test, on=['unique_id', 'ds']),
    metrics=metrics,
    models=['TimeGPT']
)
evaluation
unique_idmetricTimeGPT
0DEmae9.002193
1DErmse11.348207
plot_series(df_sub[-200:], forecasts_df= fcst_finetune_depth_df, level = [90])

3d. 使用外生变量进行预测

外生变量是外部因素或预测因子,它们不是目标时间序列的一部分,但可以影响其行为。纳入这些变量可以为模型提供额外的上下文,提高其理解数据中复杂关系和模式的能力。

要在 TimeGPT 中使用外生变量,请将输入时间序列中的每个点与相应的外部数据配对。如果在预测期间这些变量的未来值可用,请使用 X_df 参数包含它们。否则,您可以省略此参数,仅使用历史值也能看到改进。在下面的示例中,我们纳入了 8 个历史外生变量及其在测试期间的值,这将 MAE 和 RMSE 分别降低到 4.6 和 6.4。

df_train.head()
unique_iddsyExogenous1Exogenous2day_0day_1day_2day_3day_4day_5day_6
1680DE2017-10-22 00:00:0019.1016972.7515778.929750.00.00.00.00.00.01.0
1681DE2017-10-22 01:00:0019.0316254.5016664.209500.00.00.00.00.00.01.0
1682DE2017-10-22 02:00:0016.9015940.2517728.749500.00.00.00.00.00.01.0
1683DE2017-10-22 03:00:0012.9815959.5018578.138500.00.00.00.00.00.01.0
1684DE2017-10-22 04:00:009.2416071.5019389.167500.00.00.00.00.00.01.0
future_ex_vars_df = df_test.drop(columns = ['y'])
future_ex_vars_df.head()
unique_iddsExogenous1Exogenous2day_0day_1day_2day_3day_4day_5day_6
3312DE2017-12-29 00:00:0017347.0024577.926500.00.00.00.01.00.00.0
3313DE2017-12-29 01:00:0016587.2524554.319500.00.00.00.01.00.00.0
3314DE2017-12-29 02:00:0016396.0024651.454750.00.00.00.01.00.00.0
3315DE2017-12-29 03:00:0016481.2524666.043000.00.00.00.01.00.00.0
3316DE2017-12-29 04:00:0016827.7524403.333500.00.00.00.01.00.00.0
fcst_ex_vars_df = nixtla_client.forecast(df=df_train,
                                         X_df=future_ex_vars_df,
                                         h=24*2,
                                         level=[90, 95])
INFO:nixtla.nixtla_client:Validating inputs...
INFO:nixtla.nixtla_client:Inferred freq: h
INFO:nixtla.nixtla_client:Preprocessing dataframes...
WARNING:nixtla.nixtla_client:The specified horizon "h" exceeds the model horizon, this may lead to less accurate forecasts. Please consider using a smaller horizon.
INFO:nixtla.nixtla_client:Using future exogenous features: ['Exogenous1', 'Exogenous2', 'day_0', 'day_1', 'day_2', 'day_3', 'day_4', 'day_5', 'day_6']
INFO:nixtla.nixtla_client:Calling Forecast Endpoint...
evaluation = evaluate(
    fcst_ex_vars_df.merge(df_test, on=['unique_id', 'ds']),
    metrics=metrics,
    models=['TimeGPT']
)
evaluation
unique_idmetricTimeGPT
0DEmae4.602594
1DErmse6.358831
plot_series(df_sub[-200:], forecasts_df= fcst_ex_vars_df, level = [90])

3d. TimeGPT 用于长周期预测

当预测周期过长时,预测结果可能不够准确。TimeGPT 在预测周期短于时间序列完整周期的情况下表现最佳。对于较长的预测周期,切换到 timegpt-1-long-horizon 模型可以产生更好的结果。您可以使用 model 参数指定此模型。

在此处使用的电价时间序列中,一个周期是 24 步(代表一天)。由于我们正在预测未来两天(48 步),使用 timegpt-1-long-horizon 显著提高了预测准确性,将 MAE 降低到 6.4,RMSE 降低到 7.7。

fcst_long_df = nixtla_client.forecast(df=df_train[['unique_id', 'ds', 'y']],
                                          h=24*2,
                                          model = 'timegpt-1-long-horizon',
                                          level=[90, 95])
INFO:nixtla.nixtla_client:Validating inputs...
INFO:nixtla.nixtla_client:Inferred freq: h
INFO:nixtla.nixtla_client:Preprocessing dataframes...
INFO:nixtla.nixtla_client:Querying model metadata...
INFO:nixtla.nixtla_client:Restricting input...
INFO:nixtla.nixtla_client:Calling Forecast Endpoint...
evaluation = evaluate(
    fcst_long_df.merge(df_test, on=['unique_id', 'ds']),
    metrics=metrics,
    models=['TimeGPT']
)
evaluation
unique_idmetricTimeGPT
0DEmae6.365540
1DErmse7.738188
plot_series(df_sub[-200:], forecasts_df= fcst_long_df, level = [90])

4. 结论和下一步

在本 notebook 中,我们演示了四种提高 TimeGPT 预测准确性的有效策略

  1. 增加微调步数。
  2. 调整微调损失函数。
  3. 纳入外生变量。
  4. 对于扩展预测周期,切换到长周期模型。

我们鼓励您尝试调整这些超参数,以确定最适合您特定需求的最佳设置。此外,请参阅我们的文档以了解更多功能,例如模型可解释性等。

在提供的示例中,应用这些方法后,我们观察到预测准确性指标有了显著改进,总结如下。

结果摘要

步骤描述MAEMAE 改进 (%)RMSERMSE 改进 (%)
0零样本 TimeGPT18.5N/A20.0N/A
1增加微调步数11.538%12.637%
2调整微调损失函数9.648%11.045%
3微调更多参数9.051%11.344%
4添加外生变量4.675%6.468%
5切换到长周期模型6.465%7.762%