Skip to content

How to Choose a Forecasting Method

This guide walks you through selecting the right forecasting approach for your data. Start with the quick reference table to find your scenario, then follow the relevant section for setup details.

Prerequisites

Try it interactively

How to Choose a Forecasting Method

Interactive decision guide progressing from SeasonalNaive baseline through linear reduction, stationarity transforms, feature enrichment, nonlinear models, decomposition, and prediction intervals.

ViewOpen in marimo

Quick Reference

Scenario Recommended starting point
Quick benchmark, any series SeasonalNaive
Few features, short horizon PointReductionForecaster + Ridge
Strong trend or seasonality DecompositionPipeline
Many features, nonlinear patterns PointReductionForecaster + GradientBoostingRegressor
Multiple related series Panel forecasting with panel_strategy="global" (default)
Uncertainty quantification needed SplitConformalForecaster wrapping the chosen point forecaster
Only probabilistic forecasts needed IntervalReductionForecaster with a quantile or interval regressor directly
Categorical targets ClassProbaReductionForecaster with an sklearn classifier
Combining multiple forecasters VotingPointForecaster or VotingIntervalForecaster

1. Establish a Naive Baseline

Always start here. SeasonalNaive gives you a score to beat with zero tuning. Set the seasonality to match the dominant cycle in your data (7 for daily with weekly pattern, 12 for monthly with yearly pattern, 1 for non-seasonal):

from yohou.point import SeasonalNaive

baseline = SeasonalNaive(seasonality=7)
baseline.fit(y_train, forecasting_horizon=14)
y_pred_baseline = baseline.predict()

Evaluate with cross-validation to establish the score to beat. See Evaluate Forecast Accuracy for details.

2. Try a Linear Reduction Model

If the baseline is not accurate enough, fit a PointReductionForecaster with a linear estimator:

from sklearn.linear_model import Ridge
from yohou.point import PointReductionForecaster

forecaster = PointReductionForecaster(estimator=Ridge())
forecaster.fit(y_train, X_actual=X_train, forecasting_horizon=14)

If this does not improve on the baseline, the data likely has nonlinear patterns or the exogenous features do not carry useful signal. Skip to step 5.

3. Handle Non-stationarity with Target Transformers

If the series has trend or changing variance, add a target transformer such as SeasonalDifferencing or LogTransformer:

from yohou.stationarity import SeasonalDifferencing, LogTransformer

# Remove weekly seasonality before fitting
forecaster = PointReductionForecaster(
    estimator=Ridge(),
    target_transformer=SeasonalDifferencing(seasonality=7),
)

# Or stabilize multiplicative variance
forecaster = PointReductionForecaster(
    estimator=Ridge(),
    target_transformer=LogTransformer(),
)

See Apply Stationarity Transforms for the full procedure and Stationarity for guidance on choosing the right transform.

4. Enrich the Feature Set

Add feature transformers one group at a time. Combine LagTransformer, RollingStatisticsTransformer, and other transformers using FeatureUnion. Check whether cross-validation scores improve after each addition:

from yohou.preprocessing import LagTransformer, RollingStatisticsTransformer
from yohou.compose import FeatureUnion

feature_transformer = FeatureUnion(
    transformer_list=[
        ("lags", LagTransformer(lag=[1, 7, 14])),
        ("rolling_7", RollingStatisticsTransformer(window_size=7)),
        ("rolling_14", RollingStatisticsTransformer(window_size=14)),
    ]
)

forecaster = PointReductionForecaster(
    estimator=Ridge(),
    feature_transformer=feature_transformer,
)

See Build Reduction Forecasters for the full walkthrough of feature and target transformer composition.

5. Switch to Gradient Boosting

If the linear model plateaus, swap in a nonlinear estimator:

from sklearn.ensemble import GradientBoostingRegressor

forecaster = PointReductionForecaster(
    estimator=GradientBoostingRegressor(n_estimators=200),
    target_transformer=SeasonalDifferencing(seasonality=7),
    feature_transformer=feature_transformer,
)

Use RandomizedSearchCV to explore the hyperparameter space efficiently. See Tune Hyperparameters for the full procedure.

6. Choose the Reduction Strategy

The default "multi-output" strategy works well for short horizons. For longer horizons, switch to "direct" or "dir-rec":

# One model per horizon step (no error propagation)
forecaster = PointReductionForecaster(
    estimator=Ridge(),
    reduction_strategy="direct",
    n_jobs=-1,
)

# Direct with recursive features (balanced)
forecaster = PointReductionForecaster(
    estimator=Ridge(),
    reduction_strategy="dir-rec",
)

See Reduction Forecasting for background on how each strategy handles error propagation.

7. Use Decomposition for Complex Seasonality

If the series has multiple seasonal components or strong trend, a DecompositionPipeline separates the problem into simpler parts. Use PolynomialTrendForecaster for trend and FourierSeasonalityForecaster for cyclical patterns:

from yohou.compose import DecompositionPipeline
from yohou.stationarity import PolynomialTrendForecaster, FourierSeasonalityForecaster

forecaster = DecompositionPipeline(
    forecasters=[
        ("trend", PolynomialTrendForecaster(degree=1)),
        ("seasonality", FourierSeasonalityForecaster(
            seasonality=365, harmonics=[1, 2, 3, 4, 5],
        )),
        ("residual", PointReductionForecaster(estimator=Ridge())),
    ]
)

8. Add Prediction Intervals

Once you have a satisfactory point forecaster, wrap it with SplitConformalForecaster to quantify uncertainty:

from yohou.interval import SplitConformalForecaster

interval_forecaster = SplitConformalForecaster(
    point_forecaster=forecaster,
    calibration_size=100,
)
interval_forecaster.fit(y_train, X_actual=X_train, forecasting_horizon=14, coverage_rates=[0.9])
intervals = interval_forecaster.predict_interval(coverage_rates=[0.9])

If you need quantile or interval regression directly (without a point forecaster), use IntervalReductionForecaster instead. See Produce Prediction Intervals for the full procedure.

See Also