models.forecaster_recursive_lgbm_full

models.forecaster_recursive_lgbm_full

LGBM forecaster with real Bayesian tuning and SHAP.

This module provides ForecasterRecursiveLGBMFull, which combines the LightGBM forecaster from spotforecast2-safe with Bayesian hyperparameter optimisation (Optuna) and SHAP-based feature importance from ForecasterRecursiveModelFull.

Examples

from spotforecast2.models import ForecasterRecursiveLGBMFull

model = ForecasterRecursiveLGBMFull(iteration=0)
assert model.name == "lgbm"
assert model.forecaster is not None
assert model.n_trials == 10
print(f"name={model.name}, n_trials={model.n_trials}, iteration={model.iteration}")
name=lgbm, n_trials=10, iteration=0

Classes

Name Description
ForecasterRecursiveLGBMFull LGBM forecaster with real Bayesian tuning and SHAP.

ForecasterRecursiveLGBMFull

models.forecaster_recursive_lgbm_full.ForecasterRecursiveLGBMFull(
    iteration,
    lags=12,
    **kwargs,
)

LGBM forecaster with real Bayesian tuning and SHAP.

Inherits the LightGBM forecaster initialisation from ForecasterRecursiveLGBM (spotforecast2-safe) and adds the real tune() and get_global_shap_feature_importance() from ForecasterRecursiveModelFull.

The MRO ensures that tune() and SHAP methods resolve from ForecasterRecursiveModelFull, while the LightGBM-specific __init__ (estimator wiring) comes from ForecasterRecursiveLGBM.

Parameters

Name Type Description Default
iteration int Training iteration index (0-based). required
lags int Number of lag features to use. 12
**kwargs Any Forwarded to parent classes (e.g., n_trials, predict_size, train_size). {}

Examples

from spotforecast2.models import ForecasterRecursiveLGBMFull

model = ForecasterRecursiveLGBMFull(iteration=0)
assert model.name == "lgbm"
assert model.forecaster is not None
assert model.n_trials == 10
assert model.iteration == 0
print(f"name={model.name}, n_trials={model.n_trials}, iteration={model.iteration}")
print(f"tune callable: {callable(model.tune)}")
print(f"shap callable: {callable(model.get_global_shap_feature_importance)}")
name=lgbm, n_trials=10, iteration=0
tune callable: True
shap callable: True

Methods

Name Description
get_global_shap_feature_importance Return global SHAP-based feature importances.
tune Tune the forecaster via Bayesian search (Optuna).
get_global_shap_feature_importance
models.forecaster_recursive_lgbm_full.ForecasterRecursiveLGBMFull.get_global_shap_feature_importance(
    frac=0.1,
)

Return global SHAP-based feature importances.

Uses shap.TreeExplainer on the underlying estimator to compute mean absolute SHAP values across a random sample of the training data.

Parameters
Name Type Description Default
frac float Fraction of training data to sample (0 < frac <= 1). 0.1
Returns
Name Type Description
pd.Series pd.Series: Feature importances sorted descending. Empty
pd.Series if the model has not been tuned.
Raises
Name Type Description
ValueError If the forecaster has not been initialized.
Examples
import numpy as np
import pandas as pd
from spotforecast2.models import ForecasterRecursiveLGBMFull

rng = np.random.default_rng(0)
y = pd.Series(
    rng.random(30),
    index=pd.date_range("2023-01-01", periods=30, freq="h", tz="UTC"),
    name="load",
)

# Untuned: best_params is None so an empty Series is returned.
model_untuned = ForecasterRecursiveLGBMFull(iteration=0, lags=3)
model_untuned.forecaster.fit(y=y)
X_train_u, y_train_u = model_untuned.forecaster.create_train_X_y(y=y)
model_untuned._get_training_data = lambda: (X_train_u, y_train_u)

result_empty = model_untuned.get_global_shap_feature_importance()
assert isinstance(result_empty, pd.Series)
assert len(result_empty) == 0
print(f"Untuned result dtype: {result_empty.dtype}")
╭─────────────────────────────── IgnoredArgumentWarning ───────────────────────────────╮
 The number of bins has been reduced from 10 to 1 due to duplicated edges caused by   
 repeated predicted values.                                                           
                                                                                      
 Category : spotforecast2.exceptions.IgnoredArgumentWarning                           
 Location :                                                                           
 /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/spotforecast2_s 
 afe/preprocessing/_binner.py:259                                                     
 Suppress : warnings.simplefilter('ignore', category=IgnoredArgumentWarning)          
╰──────────────────────────────────────────────────────────────────────────────────────╯
Model is not tuned — returning empty Series.
Untuned result dtype: float64
import numpy as np
import pandas as pd
from spotforecast2.models import ForecasterRecursiveLGBMFull

rng = np.random.default_rng(0)
y = pd.Series(
    rng.random(30),
    index=pd.date_range("2023-01-01", periods=30, freq="h", tz="UTC"),
    name="load",
)

model = ForecasterRecursiveLGBMFull(iteration=0, lags=3)
model.forecaster.fit(y=y)

# Set best_params and best_lags to bypass the early-return guard.
model.best_params = {}
model.best_lags = [1, 2, 3]

# Supply pre-computed training matrices to avoid live data loading.
X_train, y_train = model.forecaster.create_train_X_y(y=y)
model._get_training_data = lambda: (X_train, y_train)

importance = model.get_global_shap_feature_importance(frac=1.0)
assert isinstance(importance, pd.Series)
assert set(importance.index) == {"lag_1", "lag_2", "lag_3"}
print(f"Feature importance index: {list(importance.index)}")
print(importance)
╭─────────────────────────────── IgnoredArgumentWarning ───────────────────────────────╮
 The number of bins has been reduced from 10 to 1 due to duplicated edges caused by   
 repeated predicted values.                                                           
                                                                                      
 Category : spotforecast2.exceptions.IgnoredArgumentWarning                           
 Location :                                                                           
 /opt/hostedtoolcache/Python/3.13.13/x64/lib/python3.13/site-packages/spotforecast2_s 
 afe/preprocessing/_binner.py:259                                                     
 Suppress : warnings.simplefilter('ignore', category=IgnoredArgumentWarning)          
╰──────────────────────────────────────────────────────────────────────────────────────╯
Feature importance index: ['lag_1', 'lag_2', 'lag_3']
lag_1    0.0
lag_2    0.0
lag_3    0.0
dtype: float64
tune
models.forecaster_recursive_lgbm_full.ForecasterRecursiveLGBMFull.tune()

Tune the forecaster via Bayesian search (Optuna).

Loads time-series data, builds exogenous features, and runs bayesian_search_forecaster over the search space registered for self.name in SEARCH_SPACES.

After tuning the model is fitted with the best parameters and, if self.save_model_to_file is True, persisted to disk.

Raises
Name Type Description
KeyError If self.name is not in SEARCH_SPACES.
Examples
from spotforecast2.models import ForecasterRecursiveLGBMFull

model = ForecasterRecursiveLGBMFull(iteration=0)
assert callable(model.tune)
print(f"tune is callable: {callable(model.tune)}")
print(f"n_trials={model.n_trials}, name={model.name}")
tune is callable: True
n_trials=10, name=lgbm