MLForecastAdapter wraps a global ML model (one model fit across the
whole panel) with lags and calendar features doing the work that a
per-series statistical model does structurally.
We can then calibrate on the errors from the fitted ML model.
Fit the global model
Standard mlforecast: lags at the seasonal boundaries, calendar features, and two target transforms: a per-series standard scaler and one seasonal differencing step.Scale the panel, or the small series get no interval at allLocalStandardScaleris not decoration here. These eight series span three orders of magnitude, and a single global tree model trained on unscaled targets simply ignores the small ones — its splits are chosen to reduce error onH50, whose values are in the tens of thousands. Dropping the scaler from this pipeline takes marginal coverage from 95% to 71%, and the two smallest series (H200,H300) from 96% and 83% down to 2% and 0%. Conformal prediction cannot repair that. Calibration widens a band around a point forecast; it cannot make a forecast that ignores your series informative. Fix the model first, then calibrate it.
The one capability it lacks
MLForecastAdapter is a point forecaster only. There is no
SupportsQuantiles, so CQR is unavailable.
Why not just ask LightGBM for quantiles? SettingEverything else works.objective="quantile"fits one model per quantile, so you would need a differentMLForecastobject per level, and the adapter speaks for one model. The package does not paper over that with an abstraction that fits models behind your back. If you want interval shape from a boosted model, the supported route is SPCI, which learns the residual distribution instead.
MLForecastAdapter also rejects a few
configurations at construction rather than later: an MLForecast built
with mlforecast’s own prediction_intervals=, with static features, or
with a weight column is refused outright, because the adapter cannot
honour those semantics.
Calibrate and predict

Measured coverage
H300 and H50 at
barely half. Nothing about the calibration is wrong: the interval is
sized from cross-validation windows inside the training period, and this
holdout sits entirely after it. A global tree model’s error grows once
the forecast origin moves past where it was fitted, and a band
calibrated before that point cannot anticipate it — no conformal method
can see, from inside the training data, that the forecaster is about to
get worse. Refitting on a schedule is the structural answer.
ACI recovers a little of it (77.6%, and the better
Winkler score of the two) because evaluate feeds it the truths as it
rolls, but it is correcting a level when the problem is the point
forecast.
A global model does not give you global calibration
One LightGBM produced every forecast above, but the conformal quantile
is still taken per (series, horizon) cell. That is deliberate: a
global model’s errors are systematically different across a panel
whose series span three orders of magnitude, and pooling residuals
across them would give every series the same band — far too wide for
the small series, too narrow for the large ones.
Sharing the model across series and sharing the calibration across
series are independent choices, and this package makes the second one
for you.
Next
- StatsForecast — the same panel, per-series statistical models.
- NeuralForecast — and a neural global model.
- SPCI — varying interval width without a quantile model.

