A mlr3::Learner for iterative one-step-ahead forecasting. Wraps a mlr3pipelines::GraphLearner (held internally,
mirroring DirectForecaster and mlr3tuning::AutoTuner). Training is fully delegated to the graph. At predict time
the forecaster builds a combined task (training history + test rows with NA targets) backed by a single mutable
data.table::data.table(), iterates through the test rows in (key, order) order, and writes each prediction back
into the combined task's target column so that lag and rolling features for the next step reflect the freshly
predicted value.
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: it would entangle the transformation with the iterative lag/rolling feedback, which read the original-scale backend, producing a train/predict scale mismatch.
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 of the base learner. ReturnsNULLif the learner has not been trained.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)
#>
#> ── <PredictionRegr> for 29 observations: ───────────────────────────────────────
#> row_ids truth response month
#> 116 505 391.9375 1958-08-01
#> 117 404 391.9375 1958-09-01
#> 118 359 391.9375 1958-10-01
#> --- --- --- ---
#> 142 461 391.9375 1960-10-01
#> 143 390 391.9375 1960-11-01
#> 144 432 391.9375 1960-12-01
# 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)
#>
#> ── <PredictionRegr> for 29 observations: ───────────────────────────────────────
#> row_ids truth response month
#> 116 505 391.9375 1958-08-01
#> 117 404 391.9375 1958-09-01
#> 118 359 391.9375 1958-10-01
#> --- --- --- ---
#> 142 461 391.9375 1960-10-01
#> 143 390 391.9375 1960-11-01
#> 144 432 391.9375 1960-12-01