#> fcst.mase
#> 0.5807121
mlr3forecast
mlr3forecast?R has two strong, separate worlds for forecasting:
| Classical | ML | |
|---|---|---|
| Tools | forecast, fable, smooth |
mlr3, … |
| Models | ARIMA, ETS, Theta | boosting, forests |
Crossing the divide means glue code: hand-rolled temporal CV, lag features, no shared interface.
mlr3forecast bridges the two — bringing time series forecasting to the mlr3 ecosystem, built on:
mlr3: a unified machine learning framework in R (successor to mlr)mlr3pipelines: a dataflow programming toolkitforecast, smooth, …: established forecasting packagesA forecaster becomes just another mlr3 Learner — ready to tune, pipeline, benchmark and ensemble.
mlr3 ecosystemmlr3forecast adds forecasting tasks, learners, resamplings, and measures to the mlr3 ecosystem.
mlr3 in five verbs — now for forecastingThe same mlr3 workflow you already know:
tsk(): a forecasting task (target + time order)lrn(): a forecaster (here, auto-ARIMA)rsmp(): a temporal resamplingresample(): run the experimentmsr(): score itEverything downstream is unchanged.
A TaskFcst is a regression task plus a temporal order column (and an optional key for many series).
tsk() ships ready-made tasksas_task_fcst() wraps your own data.frameautoplot() for a quick lookBuilt-in: airpassengers, electricity, lynx, …
mlr3forecast in a nutshellLearners
regr learner → forecaster
Pipelines (mlr3pipelines)
PipeOpsTasks & resamplings
TaskFcst, global (many-series) forecastingfcst.holdout, fcst.cv (respect time)Measures
Full mlr3 integration: tuning, benchmarking, ensembling, quantile forecasts
Wrapping forecast, smooth, prophet, tscount — all fcst.*:
Quantile predict type → prediction intervals, scored with probabilistic measures (Pinball, Winkler).
#>
#> ── <PredictionRegr> for 24 observations: ───────────────────────────────────────
#> row_ids truth q0.1 q0.5 q0.9 response month
#> 1 NA 430.8905 445.6351 460.3796 445.6351 1961-01-01
#> 2 NA 403.0907 420.3953 437.6999 420.3953 1961-02-01
#> 3 NA 429.7726 449.1988 468.6249 449.1988 1961-03-01
#> --- --- --- --- --- --- ---
#> 22 NA 488.8134 528.4261 568.0389 528.4261 1962-10-01
#> 23 NA 417.7295 457.6609 497.5924 457.6609 1962-11-01
#> 24 NA 459.6531 499.8602 540.0673 499.8602 1962-12-01
recursive_forecaster() adds lag features and forecasts step by step.
direct_forecaster(), one model per horizon, no error accumulationAny mlr3 regr learner works: ranger, xgboost, glmnet, …
#>
#> ── <PredictionRegr> for 24 observations: ───────────────────────────────────────
#> row_ids truth response month
#> 1 NA 444.7887 1961-01-01
#> 2 NA 446.6875 1961-02-01
#> 3 NA 463.6715 1961-03-01
#> --- --- --- ---
#> 22 NA 526.8590 1962-10-01
#> 23 NA 512.9035 1962-11-01
#> 24 NA 506.3307 1962-12-01
mlr3pipelinesAssemble new Learners by connecting PipeOps into a Graph1 — preprocessing, feature engineering and the model in one object.
PipeOps are created with po()%>>% operatorGraph behaves like any other learnermlr3pipelinesThe same idea, applied to forecasting — the Graph is the forecaster:
Forecasting PipeOps:
fcst.lags, fcst.rolling, fcst.fourierfcst.feasts, fcst.tsfeatsfcst.targetdiff, fcst.targetboxcoxClassical and ML forecasters, compared in one benchmark() call across rolling-origin folds.
learners = list(
lrn("fcst.auto_arima", id = "auto_arima"),
lrn("fcst.ets", id = "ets"),
lrn("fcst.theta", id = "theta"),
recursive_forecaster(lrn("regr.ranger"), lags = 1:12, id = "ranger")
)
bmr = benchmark(benchmark_grid(
tasks = tsk("airpassengers"),
learners = learners,
resamplings = rsmp("fcst.cv", folds = 10, horizon = 6)
))
autoplot(bmr, measure = msr("regr.rmse")) +
labs(title = NULL, x = NULL) +
theme_minimal(base_size = 18)The Monash repository (M1–M4, tourism, energy, …) loads directly:
read_tsf(): parse any .tsf file, frequency & horizon includeddownload_zenodo_record(): fetch it straight from Zenodoas_task_fcst(): auto-detects target, time and series keydt = download_zenodo_record(
record_id = 4656222,
dataset_name = "m3_yearly_dataset"
)
# one task per series, or one global task
tasks = as_tasks_fcst(split(dt, by = "series_name", keep.by = FALSE))
learners = lrns(c("fcst.auto_arima", "fcst.ets", "fcst.theta"))
design = benchmark_grid(
tasks, learners, rsmp("fcst.holdout", ratio = 0.8)
)
bmr = benchmark(design)
bmr$aggregate(msr("fcst.mase"))mlr3 stackForecasters are ordinary learners, so the rest of the ecosystem plugs straight in:
Tuning: temporal CV inside auto_tuner()
Out of the box:
ppl("targettrafo"), fcst.targetdiff, fcst.targetboxcoxA key column turns the task into many series.
A single learner is trained jointly across all of them.
Forecasting as a first-class mlr3 task.
tune · pipeline · benchmark · ensemble — classical and ML forecasters, one interface.
Experimental & fast-moving — feedback and feature requests welcome!
Scan for the docs
useR! 2026