
Introduction
StatsForecast is a major statistical Forecasting package in the python ecosystem. I tend to think of it as one of the ‘big 3’ with the other two being Sktime and DARTS. The creators and maintainers of StatsForecast, Nixtla, have created an impressive ecosystem of time series forecasting frameworks. This work spans the gamut of the time series field and offers everything from machine learning, deep learning, and even hierarchical forecasting packages.
Today, we will be focused on their StatsForecast package which lies mainly in the ‘traditional’ realm of time series forecasting. Specifically, we will take a look at their newer release which contains a new type of hybrid method that blurs the lines of what makes a forecasting method ‘traditional’. This method has emerged as the top performer in Statsforecast across many benchmarks and, more recently, was the most used stat method in the top results for the VN1 Forecasting competition.
First, a quick asterisk: I am extremely biased, as I should be, since I created this method!
The MFLES Method

MFLES is a method to forecast time series based on Gradient Boosted Time Series Decomposition which treats traditional decomposition as the base estimator in the boosting process. Unlike normal Gradient Boosting, learning rates are applied at the component level (trend/seasonality/exogenous) rather than the total estimator.
The method derives its name from some of the underlying estimators that can enter into the boosting procedure, specifically: a simple Median, Fourier functions for seasonality, a simple/piecewise Linear trend, and Exponential Smoothing.
MFLES seems to do pretty good at a wide range of forecasting activity such as multiple seasonality or highly variable history.
Gradient Boosted Time Series Decomposition Theory
Let’s do a quick overview of the ‘theory’ under the hood.
The idea is pretty simple, take a process like decomposition and view it as a type of ‘psuedo’ gradient boosting since we are passing residuals around similar to standard gradient boosting. Then apply gradient boosting approaches such as iterating with a global mechanism to control the process and introduce learning rates for each of the components in the process such as trend or seasonality or exogenous. By doing this we graduate from this ‘psuedo’ approach to full blown gradient boosting.
Utilizing gradient boosting in this manner unlocks a plethora of features in the time series context.
For example, we can estimate a single seasonality period each boosting round. Effectively generalizing the process to fit infinite seasonalities. We can search for a single changepoint each round and, through boosting, fit for as many changepoints as your heart desires! Finally, we are able to merge many estimators for the various components that have traditionally been seen as ‘exotic’ to time series decomposition due to eating too much signal and not leaving much for the other components to learn from.
Of course, these all can lead to overfitting and other issues which we counteract by utilizing the component learning rates!
The process may sound complicated but it is really quite simple. Hopefully this illustration drives home the main idea.

If you are still interested in learning more, you can check out some of my other articles on ThymeBoost which implements this idea.
Time Series Forecasting with ThymeBoost
The M4 Forecasting Compeition with ThymeBoost
Ultimately, MFLES is a specific implementation of ThymeBoost that tends to work well!
A Quick Example
Now that we have reviewed some of the underlying theory and specific details of MFLES, let’s take a look at forecasting with it using StatsForecast!
The following example can also be found in the documentation (I also wrote the documentation for the method)
For the example, we will use the infamous airline passengers dataset which has a nice trend and multiplicative seasonality.
import pandas as pd
import numpy as np
from statsforecast.models import AutoMFLES
import matplotlib.pyplot as plt
df = pd.read_csv(r'https://raw.githubusercontent.com/jbrownlee/Datasets/master/airline-passengers.csv')
y = df['Passengers'].values # make array
mfles_model = AutoMFLES(
season_length = [12],
test_size = 12,
n_windows=2,
metric = 'smape')
mfles_model.fit(y=y)
predicted = mfles_model.predict(12)['mean']
fitted = mfles_model.predict_in_sample()['fitted']
plt.plot(np.append(fitted, predicted), linestyle='dashed', color='red')
plt.plot(y)
plt.show()

There are a few parameters we pass to MFLES here, some might say too many for a method that is a type of ‘Auto’ forecasting model. Either way, let’s review a few of these key parameters:
- season_length: a list of seasonal periods, in order of perceived importance preferably.
- test_size: AutoMFLES is optimized via time series cross validation. The test size dictates how many periods to use in each test fold. This is probably the most important parameter when it comes to optimizing and you should weigh the season length, forecast horizon, and general data length when setting this. But a good rule of thumb is either the most important season length or half that to allow MFLES to pick up on seasonality.
- n_windows: how many test sets are used in optimizing parameters. In this example, 2 means that we, in total, use 24 months (12 * 2) split between the 2 windows.
- metric: this one is easy, it is simply the metric we want to optimize for with our parameters. Here we use the default which is smape that is defaulted to reproduce experiment results on M4. You can also pass ‘rmse’, ‘mape’, or ‘mae’ to optimize for another metric.
M4 Benchmark
Of course, we do not care too much about fitting to a single series. We want to know how MFLES performs on larger benchmarks. This is essentially the ‘why should I care’ about MFLES. Luckily for us there were some benchmarks done on the M4 datasets.
If you are not aware of what the M4 competition was, and subsequently what the M4 datasets are, it was a forecasting competition which took place in 2018. In terms of the dataset, the M4 dataset consisted of 100,000 time series from various domains.
Dataset Characteristics
- Data Frequency: Time series were grouped into six different frequencies:
- Yearly: 23,000 series
- Quarterly: 24,000 series
- Monthly: 48,000 series
- Weekly: 359 series
- Daily: 4227 series
- Hourly: 414 series
Domains Represented
The dataset included time series from diverse fields:
- Demographic: Population counts, birth rates, etc.
- Finance: Stock prices, currency rates, etc.
- Industry: Production quantities, energy consumption, etc.
- Macro: GDP, inflation, etc.
- Micro: Sales data from companies, stores, or products.
- Other: Various datasets that didn’t fit the above categories.
For the benchmark with MFLES, the results of which can be found here, Nixtla compared the method against many standard Statistical methods such as ARIMA, ETS, and Theta models.
The sMAPE results can be seen below:

In terms of winners—MFLES is the best method in 2 of the 6 datasets, losing out only to Theta who is best in 3. But let’s take a look at the ranks and take into account the number of series.
Here are the ranks of the methods per dataset:

Based on the benchmark, MFLES actually placed 2nd, just behind the Theta method.
What’s even more impressive is the flexibility of MFLES. The method can handle:
- Multiple Seasonality
- Exogenous Features
- Trend Changepoints
Things taht Theta doesn’t typically naturally handle. Of course, you could pull Theta into a Gradient Boosted Decomposition framework to generalize it but that is for another article!
Conclusion
In this article we took a look at MFLES, which was unleashed by Nixtla back in May 2024 and has had a pretty decent run – all things considered. There are some neat additional features that are in the pipeline for MFLES. The most interesting being a any-estimator exogenous component which will let you fit your exogenous features using any method such as boosted trees, SVMs, or even neural nets. Methods that typically would eat too much signal in a time series context.
Anyways, I hope you enjoyed this over view! As always, if you want to see more content from me then make sure to sign up to receive notifications when I publish. I’ll be better this year I promise!