A mlr3::Learner for iterative one-step-ahead forecasting: a single model is fit, then applied recursively, feeding each prediction back as a lag/rolling feature for the next step.
Can be constructed in two ways:
Simple:
RecursiveForecaster$new(learner, lags = 1:3)– internally buildspo("fcst.lags", lags = lags) %>>% learner.Graph:
RecursiveForecaster$new(graph)– takes an arbitrary mlr3pipelines::Graph or mlr3pipelines::PipeOp.
Target transformations
A target transformation (e.g. mlr_pipeops_fcst.targetdiff, mlr3pipelines::PipeOpTargetMutate)
must wrap the forecaster, not be placed inside its graph. Wrap it with
mlr3pipelines::ppl("targettrafo") so the whole series is transformed once up front, the
recursion runs entirely on the transformed scale, and predictions are inverted once at the end:
flrn = as_learner(ppl("targettrafo",
graph = RecursiveForecaster$new(lrn("regr.rpart"), lags = 1:12),
trafo_pipeop = po("fcst.targetdiff", lag = 1L)
))
flrn$train(task, split$train)
flrn$predict(task, split$test) # predictions are on the original scalePlacing a mlr3pipelines::PipeOpTargetTrafo inside the graph is not supported and is rejected at construction.
Prediction uncertainty
Only the point forecast is fed back between steps, so se/distr uncertainty does not accumulate across horizons
and intervals are too narrow for h > 1. For calibrated multi-step intervals, prefer DirectForecaster.
Super class
mlr3::Learner -> RecursiveForecaster
Active bindings
learner(mlr3::Learner)
The base regression learner.native_model(any)
The fitted model.lags(
integer()|NULL)
The lags used, orNULLif no PipeOpFcstLags is in the graph.param_set(paradox::ParamSet)
Set of hyperparameters.marshaled(
logical(1))
Whether the learner's model is currently in marshaled form.predict_type(
character(1))
Stores the currently active predict type.
Methods
RecursiveForecaster$new()
Creates a new instance of this R6 class.
Usage
RecursiveForecaster$new(
learner,
lags = NULL,
id = NULL,
param_vals = list(),
predict_type = NULL,
clone_graph = TRUE
)Arguments
learner(mlr3::Learner | mlr3pipelines::Graph | mlr3pipelines::PipeOp)
A regression learner (whenlagsis provided) or a graph/PipeOp.lags(
integer()|NULL)
The lag values to use for creating lag features. If provided,learneris wrapped withpo("fcst.lags", lags = lags). IfNULL,learnermust be a mlr3pipelines::Graph or mlr3pipelines::PipeOp.id(
character(1)|NULL)
Identifier, defaultNULL(auto-generated).param_vals(named
list())
List of hyperparameter settings.predict_type(
character(1)|NULL)
The predict type, defaultNULL.clone_graph(
logical(1))
Whether to clone the graph, defaultTRUE.
RecursiveForecaster$marshal()
Marshal the learner's model.
Arguments
...(any)
Additional arguments passed tomlr3::marshal_model().
RecursiveForecaster$unmarshal()
Unmarshal the learner's model.
Arguments
...(any)
Additional arguments passed tomlr3::unmarshal_model().
Examples
library(mlr3pipelines)
task = tsk("airpassengers")
flrn = RecursiveForecaster$new(lrn("regr.rpart"), lags = 1:3)
split = partition(task, ratio = 0.8)
flrn$train(task, split$train)
flrn$predict(task, split$test)
#>
#> ── <PredictionFcst> for 29 observations: ───────────────────────────────────────
#> month row_ids truth response
#> 1958-08-01 116 505 391.9375
#> 1958-09-01 117 404 391.9375
#> 1958-10-01 118 359 391.9375
#> --- --- --- ---
#> 1960-10-01 142 461 391.9375
#> 1960-11-01 143 390 391.9375
#> 1960-12-01 144 432 391.9375
# graph: custom preprocessing pipeline
graph = po("fcst.lags", lags = 1:3) %>>% lrn("regr.rpart")
flrn = RecursiveForecaster$new(graph)
flrn$train(task, split$train)
flrn$predict(task, split$test)
#>
#> ── <PredictionFcst> for 29 observations: ───────────────────────────────────────
#> month row_ids truth response
#> 1958-08-01 116 505 391.9375
#> 1958-09-01 117 404 391.9375
#> 1958-10-01 118 359 391.9375
#> --- --- --- ---
#> 1960-10-01 142 461 391.9375
#> 1960-11-01 143 390 391.9375
#> 1960-12-01 144 432 391.9375