Exogenous variables or external factors are crucial in time series forecasting as they provide additional information that might influence the prediction. These variables could include holiday markers, marketing spending, weather data, or any other external data that correlate with the time series data you are forecasting.

For example, if you’re forecasting ice cream sales, temperature data could serve as a useful exogenous variable. On hotter days, ice cream sales may increase.

To incorporate exogenous variables in TimeGPT, you’ll need to pair each point in your time series data with the corresponding external data.

1. Import packages

First, we import the required packages and initialize the Nixtla client.

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'
)

👍 Use an Azure AI endpoint

To use an Azure AI endpoint, remember to set also the base_url argument:

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

2. Load data

Let’s see an example on predicting day-ahead electricity prices. The following dataset contains the hourly electricity price (y column) for five markets in Europe and US, identified by the unique_id column. The columns from Exogenous1 to day_6 are exogenous variables that TimeGPT will use to predict the prices.

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. Forecasting electricity prices using future exogenous variables

To produce forecasts with future exogenous variables we have to add the future values of the exogenous variables. Let’s read this dataset. In this case, we want to predict 24 steps ahead, therefore each unique_id will have 24 observations.

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

Let’s call the forecast method, adding this information:

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

📘 Available models in Azure AI

If you are using an Azure AI endpoint, please be sure to set model="azureai":

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

For the public API, we support two models: timegpt-1 and timegpt-1-long-horizon.

By default, timegpt-1 is used. Please see this tutorial on how and when to use timegpt-1-long-horizon.

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

We can also show the importance of the features.

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

This plot shows that Exogenous1 and Exogenous2 are the most important for this forecasting task, as they have the largest weight.

3b. Forecasting electricity prices using historic exogenous variables

In the example above, we just loaded the future exogenous variables. Often, these are not available because these variables are unknown. We can also make forecasts using only historic exogenous variables. This can be done by adding the hist_exog_list argument with the list of columns of df to be considered as historical. In that case, we can pass all extra columns available in df as historic exogenous variables using hist_exog_list=['Exogenous1', 'Exogenous2', 'day_0', 'day_1', 'day_2', 'day_3', 'day_4', 'day_5', 'day_6'].

Important

If you include historic exogenous variables in your model, you are implicitly making assumptions about the future of these exogenous variables in your forecast. It is recommended to make these assumptions explicit by making use of future exogenous variables.

Let’s call the forecast method, adding 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

📘 Available models in Azure AI

If you are using an Azure AI endpoint, please be sure to set model="azureai":

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

For the public API, we support two models: timegpt-1 and timegpt-1-long-horizon.

By default, timegpt-1 is used. Please see this tutorial on how and when to use 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. Forecasting electricity prices using future and historic exogenous variables

A third option is to use both historic and future exogenous variables. For example, we might not have available the future information for Exogenous1 and Exogenous2. In this example, we drop these variables from our future exogenous dataframe (because we assume we do not know the future value of these variables), and add them to hist_exog_list to be considered as historical exogenous variables.

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...

📘 Available models in Azure AI

If you are using an Azure AI endpoint, please be sure to set model="azureai":

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

For the public API, we support two models: timegpt-1 and timegpt-1-long-horizon.

By default, timegpt-1 is used. Please see this tutorial on how and when to use 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], 
)

Note that TimeGPT informs you which variables are used as historic exogenous and which are used as future exogenous.

3d. Forecasting future exogenous variables

A fourth option in case the future exogenous variables are not available is to forecast them. Below, we’ll show you how we can also forecast Exogenous1 and Exogenous2 separately, so that you can generate the future exogenous variables in case they are not available.

# 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']]

Next, we can use TimeGPT to forecast Exogenous1 and Exogenous2. In this case, we assume these quantities can be separately forecast.

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...

📘 Available models in Azure AI

If you are using an Azure AI endpoint, please be sure to set model="azureai":

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

For the public API, we support two models: timegpt-1 and timegpt-1-long-horizon.

By default, timegpt-1 is used. Please see this tutorial on how and when to use timegpt-1-long-horizon.

We can now start creating X_df, which contains the future exogenous variables.

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)

Next, we also need to add the day_0 to day_6 future exogenous variables. These are easy: this is just the weekday, which we can extract from the ds column.

# 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)

We have now created X_df, let’s investigate it:

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

Let’s compare it to our pre-loaded version:

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

As you can see, the values for Exogenous1 and Exogenous2 are slightly different, which makes sense because we’ve made a forecast of these values with TimeGPT.

Let’s create a new forecast of our electricity prices with TimeGPT using our new X_df:

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

📘 Available models in Azure AI

If you are using an Azure AI endpoint, please be sure to set model="azureai":

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

For the public API, we support two models: timegpt-1 and timegpt-1-long-horizon.

By default, timegpt-1 is used. Please see this tutorial on how and when to use timegpt-1-long-horizon.

Let’s create a combined dataframe with the two forecasts and plot the values to compare the forecasts.

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, 
)

As you can see, we obtain a slightly different forecast if we use our forecasted exogenous variables.