Source code for autogluon.timeseries.models.ensemble.weighted.greedy

import logging
import pprint
from typing import Any

from autogluon.timeseries import TimeSeriesDataFrame

from ..ensemble_selection import fit_time_series_ensemble_selection
from .abstract import AbstractWeightedTimeSeriesEnsembleModel

logger = logging.getLogger(__name__)


[docs] class GreedyEnsemble(AbstractWeightedTimeSeriesEnsembleModel): """Greedy ensemble selection algorithm that iteratively builds an ensemble by selecting models with replacement. This class implements the Ensemble Selection algorithm by Caruana et al. [Car2004]_, which starts with an empty ensemble and repeatedly adds the model that most improves the ensemble's validation performance. Models can be selected multiple times, allowing the algorithm to assign higher effective weights to better-performing models. Other Parameters ---------------- ensemble_size : int, default = 100 Number of models (with replacement) to include in the ensemble. References ---------- .. [Car2004] Caruana, Rich, et al. "Ensemble selection from libraries of models." Proceedings of the twenty-first international conference on Machine learning. 2004. """ def __init__(self, name: str | None = None, **kwargs): if name is None: # FIXME: the name here is kept for backward compatibility. it will be called # GreedyEnsemble in v1.4 once ensemble choices are exposed name = "WeightedEnsemble" super().__init__(name=name, **kwargs) def _get_default_hyperparameters(self) -> dict[str, Any]: return {"ensemble_size": 100} def _fit( self, predictions_per_window: dict[str, list[TimeSeriesDataFrame]], data_per_window: list[TimeSeriesDataFrame], model_scores: dict[str, float] | None = None, time_limit: float | None = None, ): model_to_weight = fit_time_series_ensemble_selection( data_per_window=data_per_window, predictions_per_window=predictions_per_window, ensemble_size=self.get_hyperparameter("ensemble_size"), eval_metric=self.eval_metric, prediction_length=self.prediction_length, target=self.target, time_limit=time_limit, ) self.model_to_weight = {model: weight for model, weight in model_to_weight.items() if weight > 0} weights_for_printing = {model: round(float(weight), 2) for model, weight in self.model_to_weight.items()} logger.info(f"\tEnsemble weights: {pprint.pformat(weights_for_printing, width=200)}")