Skip to content

How to Build Reduction Forecasters

This guide shows you how to build forecasters using the reduction pattern: pick a scikit-learn estimator, configure feature engineering, and choose a multi-step prediction strategy.

Prerequisites

Try it interactively

  • How to Build a Lag-Feature Forecaster


    Chain feature and target forecasters with ForecastedFeatureForecaster when exogenous variables are unknown at prediction time and must be forecasted.

    View · Open in marimo

  • How to Use Lagged Forecasts as Features


    Compare ForecastedFeatureForecaster strategies (actual, predicted, rewind) and split ratio tuning for chaining feature and target forecasters.

    View · Open in marimo

Build a Basic Reduction Forecaster

A PointReductionForecaster converts a time series problem into a tabular regression problem. The actual_transformer generates the feature matrix, and the estimator learns the mapping from features to targets:

from yohou.datasets import fetch_tourism_monthly
from yohou.point import PointReductionForecaster
from yohou.preprocessing import LagTransformer
from sklearn.linear_model import Ridge

bunch = fetch_tourism_monthly(n_series=1)
y = bunch.frame

forecaster = PointReductionForecaster(
    estimator=Ridge(),
    actual_transformer=LagTransformer(lag=[1, 3, 6, 12]),
    reduction_strategy="multi-output",
)
forecaster.fit(y, forecasting_horizon=12)
predictions = forecaster.predict()

Any scikit-learn regressor works as the estimator. For tree-based models, see Forecast with CatBoost.

Choose a Reduction Strategy

The reduction_strategy parameter controls how the forecaster maps features to multiple forecast horizons:

  • If you want a single model that predicts all horizons at once, use "multi-output". This is the fastest option and works well when horizons share similar patterns.
  • If each horizon benefits from its own model, use "direct". This avoids error propagation between horizons at the cost of training one model per step. Use n_jobs to parallelize fitting.
  • If you want the flexibility of direct models with recursive features feeding into each, use "dir-rec".
forecaster = PointReductionForecaster(
    estimator=Ridge(),
    actual_transformer=LagTransformer(lag=[1, 3, 6, 12]),
    reduction_strategy="direct",
    n_jobs=-1,  # parallelize across horizons
)

Combine Multiple Feature Transformers

Use FeatureUnion to concatenate LagTransformer, RollingStatisticsTransformer, CalendarFeatureTransformer, and FourierFeatureTransformer into a single feature matrix:

from yohou.compose import FeatureUnion
from yohou.point import PointReductionForecaster
from yohou.preprocessing import (
    CalendarFeatureTransformer,
    FourierFeatureTransformer,
    LagTransformer,
    RollingStatisticsTransformer,
)
from sklearn.ensemble import HistGradientBoostingRegressor

forecaster = PointReductionForecaster(
    estimator=HistGradientBoostingRegressor(),
    actual_transformer=FeatureUnion([
        ("lags", LagTransformer(lag=[1, 3, 6, 12])),
        ("rolling", RollingStatisticsTransformer(window_size=12, statistics=["mean", "std"])),
        ("calendar", CalendarFeatureTransformer(features=["month", "day_of_week"])),
        ("fourier", FourierFeatureTransformer(seasonality=12, harmonics=[1, 2])),
    ]),
    reduction_strategy="direct",
)

For sequential preprocessing before feature engineering, wrap transformers in a FeaturePipeline. See Compose Feature Pipelines for details.

Control Step Feature Alignment

When using the "direct" strategy with exogenous features (X_future or X_forecast), the step_feature_alignment parameter controls which step-indexed columns each horizon's estimator sees:

  • "all" (default): every estimator sees all step columns.
  • "matched": each estimator sees only the step column for its horizon. Use this when features degrade with horizon (e.g., weather forecasts).
  • "cumulative": the estimator for step \(h\) sees step columns 1 through \(h\).
forecaster = PointReductionForecaster(
    estimator=HistGradientBoostingRegressor(),
    actual_transformer=LagTransformer(lag=[1, 2, 3]),
    reduction_strategy="direct",
    step_feature_alignment="matched",
)

Produce Prediction Intervals

IntervalReductionForecaster uses the same reduction pattern but produces prediction intervals. It accepts the same actual_transformer, reduction_strategy, and step_feature_alignment parameters:

from yohou.interval import IntervalReductionForecaster

interval_forecaster = IntervalReductionForecaster(
    actual_transformer=LagTransformer(lag=[1, 3, 6, 12]),
    reduction_strategy="multi-output",
)
interval_forecaster.fit(y, forecasting_horizon=12, coverage_rates=[0.1, 0.5, 0.9])
y_pred_int = interval_forecaster.predict_interval()

For conformal calibration on top of a point reduction forecaster, see Produce Prediction Intervals.

See Also