AI Horizon Forecast

AI Horizon Forecast

TimesFM-2.5 + External Covariates: A Practical Retail Forecasting Tutorial

Enhancing the popular foundation model with external covariates

Nikos Kafritsas's avatar
Nikos Kafritsas
Oct 30, 2025
∙ Paid
Created with DALLE*3

TimesFM-2.5 is the latest upgrade of Google’s popular foundation model.

We covered the model in depth in a previous article, including a tutorial on the KDD Cup 2018 dataset.

TimesFM-2.5: Hands-On Tutorial with Google's Upgraded Forecasting Model

TimesFM-2.5: Hands-On Tutorial with Google's Upgraded Forecasting Model

Nikos Kafritsas
·
Oct 4
Read full story

In this article, we’ll use TimesFM-2.5 to try to enhance our predictions with external covariates. Earlier versions (TimesFM-1.0 and 2.0) supported this feature, but TimesFM-2.5 does not. So:

  • I’ll port the covariate functionality to TimesFM-2.5, adapting it for full compatibility.

  • I’ll benchmark both approaches in a retail-forecasting scenario against top statistical models.

  • As usual, I’ll apply a rolling-origin forecast for rigorous evaluation over a larger test set and multiple prediction windows.

Let’s get started!

✅ Find the full notebook for this article here: AI Projects Folder (Project 25)


Prelimaries - Covariate Handling

First, let’s see how earlier TimesFM versions handled external covariates.

Specifically, they fit a linear model using past input data and external covariates, as implemented in xreg_lib.py . This module supports several covariate types:

  • Static Categorical Covariate: constant per series, categorical (e.g., Category).

  • Static Numerical Covariate: constant per series, numerical (e.g., Base_price).

  • Dynamic Categorical Covariate: varies over time, categorical (e.g., Weekday, Has_promotion).

  • Dynamic Numerical Covariate: varies over time, numerical (e.g., Planned daily promotions).

However, Times-FM doesn’t support past observed inputs. For instance, in weather forecasting, future air pressure values are unknown—so they can’t serve as Dynamic Numerical Covariates (think of these as known future inputs).

TimesFM offers 2 modes:

  • Timesfm + Xreg: Generate the TimesFM forecast, then fit a linear model on the residuals using the external covariates.

  • Xreg + Timesfm: Fit a linear model of the series on the external covariates, then forecast the residuals with TimesFM.

By checking the code, let’s see what happens under the hood:

Option 1 — “TimesFM + XReg”

  • Generate TimesFM predictions (both in-sample and out-of-sample over the forecast horizon).

  • Then, compute the residuals as timesfm[in-sample] – observed[in-sample] and fit a linear model regressing these residuals on the external covariates to obtain out_of_sample[xreg].

  • The final combined forecast is out_of_sample[timesfm] + out_of_sample[xreg].

Option 2 — “XReg + TimesFM”

  • Fit a linear model using the covariates to generate predictions (both in-sample and out-of-sample).

  • Then, compute the residuals as observed[in-sample] – xreg[in-sample] and use TimesFM to forecast these residuals (out_of_sample[timesfm]).

  • The final combined forecast is out_of_sample[xreg] + out_of_sample[timesfm].

Note: By in-sample we mean the whole training length here.

Unfortunately, we can’t use the first approach because the TimesFM-2.5 API doesn’t return in-sample predictions. Replacing them with a Naive forecast hurts performance significantly (tested!).

So, we’ll only implement option 2.


Technical Implementation

Here’s what I changed to enable covariate forecasts with TimesFM-2.5.

It’s not hard, but understanding the model’s internals is key. We have:

This post is for paid subscribers

Already a paid subscriber? Sign in
© 2025 Nikos Kafritsas
Privacy ∙ Terms ∙ Collection notice
Start your SubstackGet the app
Substack is the home for great culture