外生变量或外部因素在时间序列预测中至关重要,因为它们提供了可能影响预测的附加信息。这些变量可以包括节假日标记、营销支出、天气数据或任何其他与您正在预测的时间序列数据相关的外部数据。

例如,如果您正在预测冰淇淋销售额,温度数据就可以作为有用的外生变量。天气越热,冰淇淋销量可能会越高。

要在 TimeGPT 中纳入外生变量,您需要将时间序列数据中的每个点与相应的外部数据配对。

1. 导入软件包

首先,我们导入所需的软件包并初始化 Nixtla 客户端。

import pandas as pd
from nixtla import NixtlaClient
nixtla_client = NixtlaClient(
    # defaults to os.environ.get("NIXTLA_API_KEY")
    api_key = 'my_api_key_provided_by_nixtla'
)

👍 使用 Azure AI 端点

要使用 Azure AI 端点,请记住同时设置 base_url 参数

nixtla_client = NixtlaClient(base_url="you azure ai endpoint", api_key="your api_key")

2. 加载数据

让我们来看一个预测次日电价的例子。以下数据集包含欧洲和美国五个市场每小时电价(y 列)以及由 unique_id 列标识的市场。从 Exogenous1day_6 的列是 TimeGPT 用于预测价格的外生变量。

df = pd.read_csv('https://raw.githubusercontent.com/Nixtla/transfer-learning-time-series/main/datasets/electricity-short-with-ex-vars.csv')
df.head()
unique_iddsyExogenous1Exogenous2day_0day_1day_2day_3day_4day_5day_6
0BE2016-10-22 00:00:0070.0057253.049593.00.00.00.00.00.01.00.0
1BE2016-10-22 01:00:0037.1051887.046073.00.00.00.00.00.01.00.0
2BE2016-10-22 02:00:0037.1051896.044927.00.00.00.00.00.01.00.0
3BE2016-10-22 03:00:0044.7548428.044483.00.00.00.00.00.01.00.0
4BE2016-10-22 04:00:0037.1046721.044338.00.00.00.00.00.01.00.0

3a. 使用未来外生变量预测电价

为了使用未来外生变量进行预测,我们需要添加外生变量的未来值。让我们读取这个数据集。在这种情况下,我们想要预测未来 24 步,因此每个 unique_id 将有 24 个观测值。

future_ex_vars_df = pd.read_csv('https://raw.githubusercontent.com/Nixtla/transfer-learning-time-series/main/datasets/electricity-short-future-ex-vars.csv')
future_ex_vars_df.head()
unique_iddsExogenous1Exogenous2day_0day_1day_2day_3day_4day_5day_6
0BE2016-12-31 00:00:0070318.064108.00.00.00.00.00.01.00.0
1BE2016-12-31 01:00:0067898.062492.00.00.00.00.00.01.00.0
2BE2016-12-31 02:00:0068379.061571.00.00.00.00.00.01.00.0
3BE2016-12-31 03:00:0064972.060381.00.00.00.00.00.01.00.0
4BE2016-12-31 04:00:0062900.060298.00.00.00.00.00.01.00.0

让我们调用 forecast 方法,并添加这些信息

timegpt_fcst_ex_vars_df = nixtla_client.forecast(df=df, X_df=future_ex_vars_df, h=24, level=[80, 90])
timegpt_fcst_ex_vars_df.head()
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: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...
unique_iddsTimeGPTTimeGPT-hi-80TimeGPT-hi-90TimeGPT-lo-80TimeGPT-lo-90
0BE2016-12-31 00:00:0051.63283061.59882066.08829541.66684337.177372
1BE2016-12-31 01:00:0045.75087754.61198860.17644536.88976731.325312
2BE2016-12-31 02:00:0039.65054346.25621052.84280833.04487626.458277
3BE2016-12-31 03:00:0034.00007244.01531047.42900023.98483520.571144
4BE2016-12-31 04:00:0033.78537043.14050348.58124024.43023918.989498

📘 Azure AI 中可用的模型

如果您使用的是 Azure AI 端点,请务必设置 model="azureai"

nixtla_client.forecast(..., model="azureai")

对于公共 API,我们支持两种模型:timegpt-1timegpt-1-long-horizon

默认情况下,使用 timegpt-1。关于如何以及何时使用 timegpt-1-long-horizon,请参阅本教程

nixtla_client.plot(
    df[['unique_id', 'ds', 'y']], 
    timegpt_fcst_ex_vars_df, 
    max_insample_length=365, 
    level=[80, 90], 
)

我们还可以展示特征的重要性。

nixtla_client.weights_x.plot.barh(x='features', y='weights')

该图显示 Exogenous1Exogenous2 对于此预测任务最重要,因为它们的权重最大。

3b. 使用历史外生变量预测电价

在上面的示例中,我们只加载了未来外生变量。通常,这些变量不可用,因为它们是未知的。我们也可以仅使用历史外生变量进行预测。这可以通过添加 hist_exog_list 参数来实现,该参数包含 df 中要视为历史数据的列列表。在这种情况下,我们可以使用 hist_exog_list=['Exogenous1', 'Exogenous2', 'day_0', 'day_1', 'day_2', 'day_3', 'day_4', 'day_5', 'day_6']df 中所有额外的列作为历史外生变量传递。

重要提示

如果您在模型中包含历史外生变量,则您的预测隐含地对这些外生变量的未来做出了假设。建议通过使用未来外生变量来明确这些假设。

让我们调用 forecast 方法,并添加 hist_exog_list 参数

timegpt_fcst_hist_ex_vars_df = nixtla_client.forecast(
    df=df, 
    h=24, 
    level=[80, 90], 
    hist_exog_list=['Exogenous1', 'Exogenous2', 'day_0', 'day_1', 'day_2', 'day_3', 'day_4', 'day_5', 'day_6'],
)
timegpt_fcst_hist_ex_vars_df.head()
INFO:nixtla.nixtla_client:Validating inputs...
INFO:nixtla.nixtla_client:Inferred freq: h
INFO:nixtla.nixtla_client:Preprocessing dataframes...
INFO:nixtla.nixtla_client:Using historical 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...
unique_iddsTimeGPTTimeGPT-hi-80TimeGPT-hi-90TimeGPT-lo-80TimeGPT-lo-90
0BE2016-12-31 00:00:0047.31133057.27731761.76679037.34534032.855870
1BE2016-12-31 01:00:0047.14274056.00385061.56830638.28162832.717170
2BE2016-12-31 02:00:0047.31147453.91713760.50374040.70581034.119210
3BE2016-12-31 03:00:0047.22451457.23975060.65344237.20928033.795586
4BE2016-12-31 04:00:0047.26694556.62207862.06281737.91181032.471073

📘 Azure AI 中可用的模型

如果您使用的是 Azure AI 端点,请务必设置 model="azureai"

nixtla_client.forecast(..., model="azureai")

对于公共 API,我们支持两种模型:timegpt-1timegpt-1-long-horizon

默认情况下,使用 timegpt-1。关于如何以及何时使用 timegpt-1-long-horizon,请参阅本教程

nixtla_client.plot(
    df[['unique_id', 'ds', 'y']], 
    timegpt_fcst_hist_ex_vars_df, 
    max_insample_length=365, 
    level=[80, 90], 
)

3c. 使用未来和历史外生变量预测电价

第三种选择是同时使用历史外生变量和未来外生变量。例如,我们可能无法获取 Exogenous1Exogenous2 的未来信息。在此示例中,我们从未来外生变量数据框中删除这些变量(因为我们假设不知道这些变量的未来值),并将它们添加到 hist_exog_list 中,以便将其视为历史外生变量。

hist_cols = ["Exogenous1", "Exogenous2"]
future_ex_vars_df_limited = future_ex_vars_df.drop(columns=hist_cols)
timegpt_fcst_ex_vars_df_limited = nixtla_client.forecast(df=df, X_df=future_ex_vars_df_limited, h=24, level=[80, 90], hist_exog_list=hist_cols)
INFO:nixtla.nixtla_client:Validating inputs...
INFO:nixtla.nixtla_client:Inferred freq: h
INFO:nixtla.nixtla_client:Preprocessing dataframes...
INFO:nixtla.nixtla_client:Using future exogenous features: ['day_0', 'day_1', 'day_2', 'day_3', 'day_4', 'day_5', 'day_6']
INFO:nixtla.nixtla_client:Using historical exogenous features: ['Exogenous1', 'Exogenous2']
INFO:nixtla.nixtla_client:Calling Forecast Endpoint...

📘 Azure AI 中可用的模型

如果您使用的是 Azure AI 端点,请务必设置 model="azureai"

nixtla_client.forecast(..., model="azureai")

对于公共 API,我们支持两种模型:timegpt-1timegpt-1-long-horizon

默认情况下,使用 timegpt-1。关于如何以及何时使用 timegpt-1-long-horizon,请参阅本教程

nixtla_client.plot(
    df[['unique_id', 'ds', 'y']], 
    timegpt_fcst_ex_vars_df_limited, 
    max_insample_length=365, 
    level=[80, 90], 
)

请注意,TimeGPT 会告知您哪些变量被用作历史外生变量,哪些被用作未来外生变量。

3d. 预测未来外生变量

第四种选择是,如果未来外生变量不可用,可以预测它们。下面,我们将向您展示如何分别预测 Exogenous1Exogenous2,以便在未来外生变量不可用时生成它们。

# We read the data and create separate dataframes for the historic exogenous that we want to forecast separately.
df = pd.read_csv('https://raw.githubusercontent.com/Nixtla/transfer-learning-time-series/main/datasets/electricity-short-with-ex-vars.csv')
df_exog1 = df[['unique_id', 'ds', 'Exogenous1']]
df_exog2 = df[['unique_id', 'ds', 'Exogenous2']]

接下来,我们可以使用 TimeGPT 预测 Exogenous1Exogenous2。在这种情况下,我们假设这些量可以单独预测。

timegpt_fcst_ex1 = nixtla_client.forecast(df=df_exog1, h=24, target_col='Exogenous1')
timegpt_fcst_ex2 = nixtla_client.forecast(df=df_exog2, h=24, target_col='Exogenous2')
INFO:nixtla.nixtla_client:Validating inputs...
INFO:nixtla.nixtla_client:Inferred freq: h
INFO:nixtla.nixtla_client:Preprocessing dataframes...
INFO:nixtla.nixtla_client:Restricting input...
INFO:nixtla.nixtla_client:Calling Forecast Endpoint...
INFO:nixtla.nixtla_client:Validating inputs...
INFO:nixtla.nixtla_client:Inferred freq: h
INFO:nixtla.nixtla_client:Preprocessing dataframes...
INFO:nixtla.nixtla_client:Restricting input...
INFO:nixtla.nixtla_client:Calling Forecast Endpoint...

📘 Azure AI 中可用的模型

如果您使用的是 Azure AI 端点,请务必设置 model="azureai"

nixtla_client.forecast(..., model="azureai")

对于公共 API,我们支持两种模型:timegpt-1timegpt-1-long-horizon

默认情况下,使用 timegpt-1。关于如何以及何时使用 timegpt-1-long-horizon,请参阅本教程

现在我们可以开始创建包含未来外生变量的 X_df

timegpt_fcst_ex1 = timegpt_fcst_ex1.rename(columns={'TimeGPT':'Exogenous1'})
timegpt_fcst_ex2 = timegpt_fcst_ex2.rename(columns={'TimeGPT':'Exogenous2'})
X_df = timegpt_fcst_ex1.merge(timegpt_fcst_ex2)

接下来,我们还需要添加 day_0day_6 的未来外生变量。这很容易:这只是星期几,我们可以从 ds 列中提取。

# We have 7 days, for each day a separate column denoting 1/0
for i in range(7):
    X_df[f'day_{i}'] = 1 * (pd.to_datetime(X_df['ds']).dt.weekday == i)

现在我们已经创建了 X_df,让我们检查一下

X_df.head(10)
unique_iddsExogenous1Exogenous2day_0day_1day_2day_3day_4day_5day_6
0BE2016-12-31 00:00:0070861.41066282.5600000010
1BE2016-12-31 01:00:0067851.83064465.3700000010
2BE2016-12-31 02:00:0067246.66063257.1170000010
3BE2016-12-31 03:00:0064027.20362059.3160000010
4BE2016-12-31 04:00:0061524.08661247.0620000010
5BE2016-12-31 05:00:0063054.08662052.3120000010
6BE2016-12-31 06:00:0065199.47363457.7200000010
7BE2016-12-31 07:00:0068285.77065388.6560000010
8BE2016-12-31 08:00:0072038.48467406.8360000010
9BE2016-12-31 09:00:0072821.19068057.2400000010

让我们与我们预加载的版本进行比较

future_ex_vars_df.head(10)
unique_iddsExogenous1Exogenous2day_0day_1day_2day_3day_4day_5day_6
0BE2016-12-31 00:00:0070318.064108.00.00.00.00.00.01.00.0
1BE2016-12-31 01:00:0067898.062492.00.00.00.00.00.01.00.0
2BE2016-12-31 02:00:0068379.061571.00.00.00.00.00.01.00.0
3BE2016-12-31 03:00:0064972.060381.00.00.00.00.00.01.00.0
4BE2016-12-31 04:00:0062900.060298.00.00.00.00.00.01.00.0
5BE2016-12-31 05:00:0062364.060339.00.00.00.00.00.01.00.0
6BE2016-12-31 06:00:0064242.062576.00.00.00.00.00.01.00.0
7BE2016-12-31 07:00:0065884.063732.00.00.00.00.00.01.00.0
8BE2016-12-31 08:00:0068217.066235.00.00.00.00.00.01.00.0
9BE2016-12-31 09:00:0069921.066801.00.00.00.00.00.01.00.0

如您所见,Exogenous1Exogenous2 的值略有不同,这是合理的,因为我们使用 TimeGPT 对这些值进行了预测。

让我们使用新的 X_df 创建一个新的 TimeGPT 电价预测

timegpt_fcst_ex_vars_df_new = nixtla_client.forecast(df=df, X_df=X_df, h=24, level=[80, 90])
timegpt_fcst_ex_vars_df_new.head()
INFO:nixtla.nixtla_client:Validating inputs...
INFO:nixtla.nixtla_client:Inferred freq: h
INFO:nixtla.nixtla_client:Preprocessing dataframes...
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...
unique_iddsTimeGPTTimeGPT-hi-80TimeGPT-hi-90TimeGPT-lo-80TimeGPT-lo-90
0BE2016-12-31 00:00:0046.98722556.95321361.44268437.02123632.531765
1BE2016-12-31 01:00:0025.71913334.58024240.14470016.85802311.293568
2BE2016-12-31 02:00:0038.55352845.15919551.74579231.94786025.361261
3BE2016-12-31 03:00:0035.77192745.78716349.20085525.75669022.342999
4BE2016-12-31 04:00:0034.55511543.91024849.35098625.19998419.759243

📘 Azure AI 中可用的模型

如果您使用的是 Azure AI 端点,请务必设置 model="azureai"

nixtla_client.forecast(..., model="azureai")

对于公共 API,我们支持两种模型:timegpt-1timegpt-1-long-horizon

默认情况下,使用 timegpt-1。关于如何以及何时使用 timegpt-1-long-horizon,请参阅本教程

让我们创建一个包含这两个预测的组合数据框,并绘制这些值以比较预测结果。

timegpt_fcst_ex_vars_df = timegpt_fcst_ex_vars_df.rename(columns={'TimeGPT':'TimeGPT-provided_exogenous'})
timegpt_fcst_ex_vars_df_new = timegpt_fcst_ex_vars_df_new.rename(columns={'TimeGPT':'TimeGPT-forecasted_exogenous'})

forecasts = timegpt_fcst_ex_vars_df[['unique_id', 'ds', 'TimeGPT-provided_exogenous']].merge(timegpt_fcst_ex_vars_df_new[['unique_id', 'ds', 'TimeGPT-forecasted_exogenous']])
nixtla_client.plot(
    df[['unique_id', 'ds', 'y']], 
    forecasts, 
    max_insample_length=365, 
)

如您所见,如果我们使用预测的外生变量,我们将获得略有不同的预测结果。