1---2name: choosing-a-forecaster3description: Guides selection of the appropriate skforecast forecaster based on the user's data characteristics and requirements. Provides a decision matrix mapping use cases to forecaster classes. Use when the user is unsure which forecaster to use or asks for a recommendation.4---56# Choosing a Forecaster78## When to Use910Use this skill when the user needs help choosing a forecaster, comparing forecaster types (recursive vs direct, single vs multi-series), or understanding which skforecast class fits their problem.1112### Related skills1314- **Next**: `forecasting-single-series` (apply the chosen forecaster to one target series)15- **Next**: `forecasting-multiple-series` (apply the chosen forecaster to several series jointly)16- **Next**: `baseline-forecasting` (build and benchmark a naive baseline with `ForecasterEquivalentDate`)17- **Next**: `autocorrelation-and-lag-selection` (analyse the series dynamics before configuring `lags`)18- **Next**: `feature-engineering` (build the input feature set: calendar, rolling, exogenous)1920## Overview2122Skforecast is a **machine learning-first** library. The primary tools are the23sklearn-compatible ML forecasters (`ForecasterRecursive`, `ForecasterDirect`,24and their multi-series variants) and the zero-shot foundation models25(`ForecasterFoundation`, e.g. Chronos-2, TimesFM 2.5/3.0) - reach for an ML or a26foundation forecaster first. Statistical models (`ForecasterStats`) and naive27baselines (`ForecasterEquivalentDate`) serve as comparison benchmarks to confirm28the chosen model adds value.2930## Step 1 — How Many Series?3132| Scenario | Go to |33|----------|-------|34| **1 target series** (with or without exogenous variables) | → Step 2a |35| **Multiple series** to forecast simultaneously | → Step 2b |36| **Multiple series as drivers** to predict one target | → `ForecasterDirectMultiVariate` |37| **Categorical target** (e.g., low/medium/high) | → `ForecasterRecursiveClassifier` |3839## Step 2a — Single Series4041| Scenario | Recommended Forecaster | Why |42|----------|----------------------|-----|43| **General purpose** (start here) | `ForecasterRecursive` | Default choice. One model, recursive multi-step. Works with any sklearn-compatible estimator (LightGBM, XGBoost, CatBoost, RandomForest, etc.). Supports lags, window features, exog, differentiation, transformers, weight functions, and all probabilistic prediction methods (bootstrapping, conformal, quantiles, distributions) |44| **Horizon-dependent patterns** (e.g., predicting at 1h vs 24h requires different relationships) | `ForecasterDirect` | Trains one independent model per step — no error propagation. Better when the predictive relationship changes significantly across the forecast horizon. Requires `steps` at init; parallelizable with `n_jobs` |45| **Statistical baseline** | `ForecasterStats` | Wraps ARIMA, SARIMAX, ETS, ARAR. Use as a benchmark to compare against ML models, or when the series is very short (< 200 obs) and ML overfits |46| **Zero-shot / cold-start / no training data** | `ForecasterFoundation` | Wraps pre-trained foundation models (Chronos-2, TimesFM 2.5/3.0, Moirai-2, TabICL, TabPFN-TS, TFC-T0, Nori, TS-ICL). `fit()` only stores context — no training. Good baseline and cold-start option. See the `foundation-forecasting` skill |47| **Naive baseline** | `ForecasterEquivalentDate` | Predicts using equivalent past dates (e.g., same weekday last week). Use as a sanity-check baseline. See the `baseline-forecasting` skill |4849## Step 2b — Multiple Series5051| Scenario | Recommended Forecaster | Why |52|----------|----------------------|-----|53| **Forecast many series with a shared model** (start here) | `ForecasterRecursiveMultiSeries` | One global model learns cross-series patterns. Supports DataFrame or dict input (dict allows series with different date ranges). Encoding options: `'ordinal'` (default), `'ordinal_category'`, `'onehot'`, `None`. Supports per-series transformers, per-series differentiation, series_weights |54| **Other series are features for one target** | `ForecasterDirectMultiVariate` | All series become input features to predict a single `level`. Per-series lags via dict (`{'sales': [1,7], 'price': [1]}`). One model per step — no error propagation |55| **Deep learning / complex nonlinear patterns** | `ForecasterRnn` | Keras-based RNN/LSTM/GRU. Single model outputs all steps and levels simultaneously via 3D tensors. Only conformal intervals (no bootstrapping). Requires keras |56| **Zero-shot / pre-trained generalist** | `ForecasterFoundation` | Global zero-shot forecasts via Chronos-2 / TimesFM 2.5/3.0 / Moirai-2 / TabICL / TabPFN-TS / TFC-T0 / Nori / TS-ICL. `fit()` only stores context. Native quantile intervals. Chronos-2, TimesFM 3.0, TabICL, TabPFN-TS, TFC-T0, and Nori support exog; TimesFM 2.5 & Moirai-2 do not. See the `foundation-forecasting` skill |5758## Decision Flowchart5960```61How many series?62│63├─► 1 series64│ │65│ ├─► Is it a classification problem? ──► Yes ──► ForecasterRecursiveClassifier66│ │67│ └─► Regression (continuous target)68│ │69│ ├─► Does the forecast relationship change across the horizon?70│ │ ├─► No / Unsure ──► ForecasterRecursive ← START HERE71│ │ └─► Yes (step-specific patterns) ──► ForecasterDirect72│ │73│ └─► Compare with baselines:74│ ├─► ForecasterStats (Auto-ARIMA, ETS) as statistical benchmark75│ └─► ForecasterEquivalentDate as naive benchmark76│77└─► Multiple series78 │79 ├─► Want to forecast ALL series (global model)?80 │ └─► ForecasterRecursiveMultiSeries ← START HERE81 │82 ├─► Want to use other series AS FEATURES for one target?83 │ └─► ForecasterDirectMultiVariate84 │85 └─► Need deep learning for very complex patterns?86 └─► ForecasterRnn8788Zero-shot / no training data / cold-start (single or multi-series)?89 └─► ForecasterFoundation (Chronos-2 / TimesFM 2.5/3.0 / Moirai-2 / TabICL / TabPFN-TS / TFC-T0 / Nori/ TS-ICL)90```9192## Key Comparisons9394### Recursive vs Direct (Single Series)9596| Aspect | ForecasterRecursive | ForecasterDirect |97|--------|-------------------|-----------------|98| Models trained | 1 | N (one per step) |99| Error propagation | Yes (predictions feed into next step) | No (each step uses only observed data) |100| Forecast horizon | Flexible (any `steps` at predict time) | Fixed at init (`steps` required) |101| Training speed | Fast (one model) | Slower (N models, parallelizable via `n_jobs`) |102| Memory | Lower (1 estimator) | Higher (N estimators stored in `estimators_` dict) |103| Best for | Most cases, especially short-to-medium horizons | Long horizons where patterns change per step |104| Prediction intervals | Bootstrapping + conformal | Bootstrapping + conformal |105106### RecursiveMultiSeries vs DirectMultiVariate (Multiple Series)107108| Aspect | ForecasterRecursiveMultiSeries | ForecasterDirectMultiVariate |109|--------|-------------------------------|------------------------------|110| Goal | Forecast **all series** with one model | Use all series as **features** for one target |111| Input | DataFrame or dict of Series | DataFrame (all series as columns) |112| Target | All series (selected via `levels`) | One series (specified via `level`) |113| Strategy | Recursive (1 model, predictions feed back) | Direct (1 model per step, no error propagation) |114| Series identification | Encoding: `'ordinal'`, `'ordinal_category'`, `'onehot'`, `None` | All series create separate lag columns |115| Series with different ranges | Yes (via dict input) | No (all must share same range) |116| Per-series lags | No (same lags for all) | Yes (dict: `{'sales': [1,7], 'price': [1]}`) |117| Series weights | Yes (`series_weights` param) | No |118| Per-series transformers | Yes (`transformer_series` dict) | Yes (`transformer_series` dict) |119| Per-series differentiation | Yes (`differentiation` dict) | Yes (via `differentiator_` per series) |120121### ML Forecasters vs Statistical Models122123| Aspect | ML Forecasters | ForecasterStats |124|--------|---------------|-----------------|125| **Primary role** | Main forecasting tools | Comparison baseline |126| Best for | Medium-to-large datasets, complex patterns, many exogenous features | Short series, interpretability, parametric intervals |127| Estimators | Any sklearn-compatible (LightGBM, XGBoost, RF, etc.) | Arima, Sarimax, Ets, Arar |128| Lags / window features | Full support (`lags`, `RollingFeatures`) | No (model handles its own structure) |129| Differentiation | Built-in (`differentiation` param) | Handled within model (e.g., ARIMA `d` parameter) |130| Exogenous variables | Full support | Only SARIMAX |131| Prediction intervals | Bootstrapping (binned residuals) + conformal | Built-in parametric |132| Tuning | `grid_search_forecaster`, `random_search_forecaster`, `bayesian_search_forecaster` | `grid_search_stats`, `random_search_stats` |133| Backtesting | `backtesting_forecaster` / `backtesting_forecaster_multiseries` | `backtesting_stats` |134| Feature selection | `select_features` / `select_features_multiseries` | Not applicable |135136## Feature Support Matrix137138| Feature | Recursive | Direct | RecursiveMultiSeries | DirectMultiVariate | Rnn | Stats | EquivalentDate | Classifier |139|---------|:---------:|:------:|:-------------------:|:-----------------:|:---:|:-----:|:--------------:|:----------:|140| Lags | ✓ | ✓ | ✓ | ✓ (per-series dict) | ✓ | — | — | ✓ |141| Window features (`RollingFeatures`) | ✓ | ✓ | ✓ | ✓ | — | — | — | ✓ |142| Exogenous variables | ✓ | ✓ | ✓ | ✓ | ✓ | SARIMAX only | — | ✓ |143| Differentiation | ✓ | ✓ | ✓ (per-series) | ✓ (per-series) | — | Within model | — | — |144| Transformer y/series | ✓ | ✓ | ✓ (per-series) | ✓ (per-series) | ✓ | ✓ | — | — |145| Transformer exog | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | — | ✓ |146| Weight function | ✓ | ✓ | ✓ (per-series) | ✓ | — | — | — | ✓ |147| Bootstrapping intervals | ✓ | ✓ | ✓ | ✓ | — | — | — | — |148| Conformal intervals | ✓ | ✓ | ✓ | ✓ | ✓ | — | ✓ | — |149| Binned residuals | ✓ | ✓ | ✓ | ✓ | ✓ | — | ✓ | — |150| Quantile predictions | ✓ | ✓ | ✓ | ✓ | — | — | — | — |151| Distribution fitting | ✓ | ✓ | ✓ | ✓ | — | — | — | — |152| Class probabilities | — | — | — | — | — | — | — | ✓ |153| Feature importances | ✓ | ✓ | ✓ | ✓ | — | — | — | — |154155> **Legend:** ✓ = supported, — = not supported/not applicable.156157## Next Steps158159Once you have chosen a forecaster, follow these steps to get started:1601611. **Define your problem**: 1 series → `ForecasterRecursive`; multiple series → `ForecasterRecursiveMultiSeries`1622. **Choose an estimator**: LightGBM (`LGBMRegressor`) is the best starting point — fast, handles categoricals, good defaults1633. **Add features**: Use `RollingFeatures` (rolling mean, std, min, max) and `CalendarFeatures` or `create_calendar_features` as exogenous variables1644. **Handle non-stationarity**: Use the `differentiation` parameter instead of manual differencing1655. **Evaluate with backtesting**: `backtesting_forecaster` + `TimeSeriesFold` for realistic multi-step evaluation1666. **Tune hyperparameters**: `bayesian_search_forecaster` (Optuna-based) — can include `lags` in the search space1677. **Add prediction intervals**: `predict_interval(method='bootstrapping', use_binned_residuals=True)` for uncertainty quantification1688. **Compare with baselines**: Use `ForecasterStats` (Auto-ARIMA: `Arima(order=None)`) and `ForecasterEquivalentDate` to verify the ML model adds value