autogluon.timeseries 1.0.1b20240304__py3-none-any.whl → 1.4.1b20251210__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of autogluon.timeseries might be problematic. Click here for more details.
- autogluon/timeseries/configs/__init__.py +3 -2
- autogluon/timeseries/configs/hyperparameter_presets.py +62 -0
- autogluon/timeseries/configs/predictor_presets.py +84 -0
- autogluon/timeseries/dataset/ts_dataframe.py +339 -186
- autogluon/timeseries/learner.py +192 -60
- autogluon/timeseries/metrics/__init__.py +55 -11
- autogluon/timeseries/metrics/abstract.py +96 -25
- autogluon/timeseries/metrics/point.py +186 -39
- autogluon/timeseries/metrics/quantile.py +47 -20
- autogluon/timeseries/metrics/utils.py +6 -6
- autogluon/timeseries/models/__init__.py +13 -7
- autogluon/timeseries/models/abstract/__init__.py +2 -2
- autogluon/timeseries/models/abstract/abstract_timeseries_model.py +533 -273
- autogluon/timeseries/models/abstract/model_trial.py +10 -10
- autogluon/timeseries/models/abstract/tunable.py +189 -0
- autogluon/timeseries/models/autogluon_tabular/__init__.py +2 -0
- autogluon/timeseries/models/autogluon_tabular/mlforecast.py +369 -215
- autogluon/timeseries/models/autogluon_tabular/per_step.py +513 -0
- autogluon/timeseries/models/autogluon_tabular/transforms.py +67 -0
- autogluon/timeseries/models/autogluon_tabular/utils.py +3 -51
- autogluon/timeseries/models/chronos/__init__.py +4 -0
- autogluon/timeseries/models/chronos/chronos2.py +361 -0
- autogluon/timeseries/models/chronos/model.py +738 -0
- autogluon/timeseries/models/chronos/utils.py +369 -0
- autogluon/timeseries/models/ensemble/__init__.py +35 -2
- autogluon/timeseries/models/ensemble/{abstract_timeseries_ensemble.py → abstract.py} +50 -26
- autogluon/timeseries/models/ensemble/array_based/__init__.py +3 -0
- autogluon/timeseries/models/ensemble/array_based/abstract.py +236 -0
- autogluon/timeseries/models/ensemble/array_based/models.py +73 -0
- autogluon/timeseries/models/ensemble/array_based/regressor/__init__.py +12 -0
- autogluon/timeseries/models/ensemble/array_based/regressor/abstract.py +88 -0
- autogluon/timeseries/models/ensemble/array_based/regressor/linear_stacker.py +167 -0
- autogluon/timeseries/models/ensemble/array_based/regressor/per_quantile_tabular.py +94 -0
- autogluon/timeseries/models/ensemble/array_based/regressor/tabular.py +107 -0
- autogluon/timeseries/models/ensemble/ensemble_selection.py +167 -0
- autogluon/timeseries/models/ensemble/per_item_greedy.py +162 -0
- autogluon/timeseries/models/ensemble/weighted/__init__.py +8 -0
- autogluon/timeseries/models/ensemble/weighted/abstract.py +40 -0
- autogluon/timeseries/models/ensemble/weighted/basic.py +78 -0
- autogluon/timeseries/models/ensemble/weighted/greedy.py +57 -0
- autogluon/timeseries/models/gluonts/__init__.py +3 -1
- autogluon/timeseries/models/gluonts/abstract.py +583 -0
- autogluon/timeseries/models/gluonts/dataset.py +109 -0
- autogluon/timeseries/models/gluonts/{torch/models.py → models.py} +185 -44
- autogluon/timeseries/models/local/__init__.py +1 -10
- autogluon/timeseries/models/local/abstract_local_model.py +150 -97
- autogluon/timeseries/models/local/naive.py +31 -23
- autogluon/timeseries/models/local/npts.py +6 -2
- autogluon/timeseries/models/local/statsforecast.py +99 -112
- autogluon/timeseries/models/multi_window/multi_window_model.py +99 -40
- autogluon/timeseries/models/registry.py +64 -0
- autogluon/timeseries/models/toto/__init__.py +3 -0
- autogluon/timeseries/models/toto/_internal/__init__.py +9 -0
- autogluon/timeseries/models/toto/_internal/backbone/__init__.py +3 -0
- autogluon/timeseries/models/toto/_internal/backbone/attention.py +196 -0
- autogluon/timeseries/models/toto/_internal/backbone/backbone.py +262 -0
- autogluon/timeseries/models/toto/_internal/backbone/distribution.py +70 -0
- autogluon/timeseries/models/toto/_internal/backbone/kvcache.py +136 -0
- autogluon/timeseries/models/toto/_internal/backbone/rope.py +89 -0
- autogluon/timeseries/models/toto/_internal/backbone/rotary_embedding_torch.py +342 -0
- autogluon/timeseries/models/toto/_internal/backbone/scaler.py +305 -0
- autogluon/timeseries/models/toto/_internal/backbone/transformer.py +333 -0
- autogluon/timeseries/models/toto/_internal/dataset.py +165 -0
- autogluon/timeseries/models/toto/_internal/forecaster.py +423 -0
- autogluon/timeseries/models/toto/dataloader.py +108 -0
- autogluon/timeseries/models/toto/hf_pretrained_model.py +118 -0
- autogluon/timeseries/models/toto/model.py +236 -0
- autogluon/timeseries/predictor.py +826 -305
- autogluon/timeseries/regressor.py +253 -0
- autogluon/timeseries/splitter.py +10 -31
- autogluon/timeseries/trainer/__init__.py +2 -3
- autogluon/timeseries/trainer/ensemble_composer.py +439 -0
- autogluon/timeseries/trainer/model_set_builder.py +256 -0
- autogluon/timeseries/trainer/prediction_cache.py +149 -0
- autogluon/timeseries/trainer/trainer.py +1298 -0
- autogluon/timeseries/trainer/utils.py +17 -0
- autogluon/timeseries/transforms/__init__.py +2 -0
- autogluon/timeseries/transforms/covariate_scaler.py +164 -0
- autogluon/timeseries/transforms/target_scaler.py +149 -0
- autogluon/timeseries/utils/constants.py +10 -0
- autogluon/timeseries/utils/datetime/base.py +38 -20
- autogluon/timeseries/utils/datetime/lags.py +18 -16
- autogluon/timeseries/utils/datetime/seasonality.py +14 -14
- autogluon/timeseries/utils/datetime/time_features.py +17 -14
- autogluon/timeseries/utils/features.py +317 -53
- autogluon/timeseries/utils/forecast.py +31 -17
- autogluon/timeseries/utils/timer.py +173 -0
- autogluon/timeseries/utils/warning_filters.py +44 -6
- autogluon/timeseries/version.py +2 -1
- autogluon.timeseries-1.4.1b20251210-py3.11-nspkg.pth +1 -0
- {autogluon.timeseries-1.0.1b20240304.dist-info → autogluon_timeseries-1.4.1b20251210.dist-info}/METADATA +71 -47
- autogluon_timeseries-1.4.1b20251210.dist-info/RECORD +103 -0
- {autogluon.timeseries-1.0.1b20240304.dist-info → autogluon_timeseries-1.4.1b20251210.dist-info}/WHEEL +1 -1
- autogluon/timeseries/configs/presets_configs.py +0 -11
- autogluon/timeseries/evaluator.py +0 -6
- autogluon/timeseries/models/ensemble/greedy_ensemble.py +0 -170
- autogluon/timeseries/models/gluonts/abstract_gluonts.py +0 -550
- autogluon/timeseries/models/gluonts/torch/__init__.py +0 -0
- autogluon/timeseries/models/presets.py +0 -325
- autogluon/timeseries/trainer/abstract_trainer.py +0 -1144
- autogluon/timeseries/trainer/auto_trainer.py +0 -74
- autogluon.timeseries-1.0.1b20240304-py3.8-nspkg.pth +0 -1
- autogluon.timeseries-1.0.1b20240304.dist-info/RECORD +0 -58
- {autogluon.timeseries-1.0.1b20240304.dist-info → autogluon_timeseries-1.4.1b20251210.dist-info/licenses}/LICENSE +0 -0
- {autogluon.timeseries-1.0.1b20240304.dist-info → autogluon_timeseries-1.4.1b20251210.dist-info/licenses}/NOTICE +0 -0
- {autogluon.timeseries-1.0.1b20240304.dist-info → autogluon_timeseries-1.4.1b20251210.dist-info}/namespace_packages.txt +0 -0
- {autogluon.timeseries-1.0.1b20240304.dist-info → autogluon_timeseries-1.4.1b20251210.dist-info}/top_level.txt +0 -0
- {autogluon.timeseries-1.0.1b20240304.dist-info → autogluon_timeseries-1.4.1b20251210.dist-info}/zip-safe +0 -0
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
import copy
|
|
2
|
-
import logging
|
|
3
|
-
import pprint
|
|
4
|
-
from typing import Dict, List, Optional
|
|
5
|
-
|
|
6
|
-
import numpy as np
|
|
7
|
-
|
|
8
|
-
import autogluon.core as ag
|
|
9
|
-
from autogluon.core.models.greedy_ensemble.ensemble_selection import EnsembleSelection
|
|
10
|
-
from autogluon.timeseries import TimeSeriesDataFrame
|
|
11
|
-
from autogluon.timeseries.metrics import TimeSeriesScorer
|
|
12
|
-
from autogluon.timeseries.models.ensemble import AbstractTimeSeriesEnsembleModel
|
|
13
|
-
from autogluon.timeseries.utils.datetime import get_seasonality
|
|
14
|
-
|
|
15
|
-
logger = logging.getLogger(__name__)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
class TimeSeriesEnsembleSelection(EnsembleSelection):
|
|
19
|
-
def __init__(
|
|
20
|
-
self,
|
|
21
|
-
ensemble_size: int,
|
|
22
|
-
metric: TimeSeriesScorer,
|
|
23
|
-
problem_type: str = ag.constants.QUANTILE,
|
|
24
|
-
sorted_initialization: bool = False,
|
|
25
|
-
bagging: bool = False,
|
|
26
|
-
tie_breaker: str = "random",
|
|
27
|
-
random_state: np.random.RandomState = None,
|
|
28
|
-
prediction_length: int = 1,
|
|
29
|
-
target: str = "target",
|
|
30
|
-
eval_metric_seasonal_period: Optional[int] = None,
|
|
31
|
-
**kwargs,
|
|
32
|
-
):
|
|
33
|
-
super().__init__(
|
|
34
|
-
ensemble_size=ensemble_size,
|
|
35
|
-
metric=metric,
|
|
36
|
-
problem_type=problem_type,
|
|
37
|
-
sorted_initialization=sorted_initialization,
|
|
38
|
-
bagging=bagging,
|
|
39
|
-
tie_breaker=tie_breaker,
|
|
40
|
-
random_state=random_state,
|
|
41
|
-
**kwargs,
|
|
42
|
-
)
|
|
43
|
-
self.prediction_length = prediction_length
|
|
44
|
-
self.target = target
|
|
45
|
-
self.eval_metric_seasonal_period = eval_metric_seasonal_period
|
|
46
|
-
|
|
47
|
-
def _fit(
|
|
48
|
-
self,
|
|
49
|
-
predictions: List[List[TimeSeriesDataFrame]], # first dim: model, second dim: val window index
|
|
50
|
-
labels: List[TimeSeriesDataFrame],
|
|
51
|
-
time_limit: Optional[int] = None,
|
|
52
|
-
sample_weight=None,
|
|
53
|
-
):
|
|
54
|
-
# Stack predictions for each model into a 3d tensor of shape [num_val_windows, num_rows, num_cols]
|
|
55
|
-
stacked_predictions = [np.stack(preds) for preds in predictions]
|
|
56
|
-
|
|
57
|
-
self.dummy_pred_per_window = []
|
|
58
|
-
self.scorer_per_window = []
|
|
59
|
-
self.data_future_per_window = []
|
|
60
|
-
|
|
61
|
-
for window_idx, data in enumerate(labels):
|
|
62
|
-
dummy_pred = copy.deepcopy(predictions[0][window_idx])
|
|
63
|
-
# This should never happen; sanity check to make sure that all predictions have the same index
|
|
64
|
-
assert all(dummy_pred.index.equals(pred[window_idx].index) for pred in predictions)
|
|
65
|
-
|
|
66
|
-
self.dummy_pred_per_window.append(dummy_pred)
|
|
67
|
-
|
|
68
|
-
scorer = copy.deepcopy(self.metric)
|
|
69
|
-
# Split the observed time series once to avoid repeated computations inside the evaluator
|
|
70
|
-
data_past = data.slice_by_timestep(None, -self.prediction_length)
|
|
71
|
-
data_future = data.slice_by_timestep(-self.prediction_length, None)
|
|
72
|
-
scorer.save_past_metrics(data_past, target=self.target, seasonal_period=self.eval_metric_seasonal_period)
|
|
73
|
-
self.scorer_per_window.append(scorer)
|
|
74
|
-
self.data_future_per_window.append(data_future)
|
|
75
|
-
|
|
76
|
-
super()._fit(
|
|
77
|
-
predictions=stacked_predictions,
|
|
78
|
-
labels=data_future,
|
|
79
|
-
time_limit=time_limit,
|
|
80
|
-
)
|
|
81
|
-
self.dummy_pred_per_window = None
|
|
82
|
-
self.evaluator_per_window = None
|
|
83
|
-
self.data_future_per_window = None
|
|
84
|
-
|
|
85
|
-
def _calculate_regret(self, y_true, y_pred_proba, metric=None, sample_weight=None): # noqa
|
|
86
|
-
# Compute average score across all validation windows
|
|
87
|
-
total_score = 0.0
|
|
88
|
-
for window_idx, data_future in enumerate(self.data_future_per_window):
|
|
89
|
-
dummy_pred = self.dummy_pred_per_window[window_idx]
|
|
90
|
-
dummy_pred[list(dummy_pred.columns)] = y_pred_proba[window_idx]
|
|
91
|
-
# We use scorer.compute_metric instead of scorer.score to avoid repeated calls to scorer.save_past_metrics
|
|
92
|
-
metric_value = self.scorer_per_window[window_idx].compute_metric(
|
|
93
|
-
data_future, dummy_pred, target=self.target
|
|
94
|
-
)
|
|
95
|
-
total_score += metric.sign * metric_value
|
|
96
|
-
avg_score = total_score / len(self.data_future_per_window)
|
|
97
|
-
# score: higher is better, regret: lower is better, so we flip the sign
|
|
98
|
-
return -avg_score
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
class TimeSeriesGreedyEnsemble(AbstractTimeSeriesEnsembleModel):
|
|
102
|
-
"""Constructs a weighted ensemble using the greedy Ensemble Selection algorithm."""
|
|
103
|
-
|
|
104
|
-
def __init__(self, name: str, ensemble_size: int = 100, **kwargs):
|
|
105
|
-
super().__init__(name=name, **kwargs)
|
|
106
|
-
self.ensemble_size = ensemble_size
|
|
107
|
-
self.model_to_weight: Dict[str, float] = {}
|
|
108
|
-
|
|
109
|
-
def _fit_ensemble(
|
|
110
|
-
self,
|
|
111
|
-
predictions_per_window: Dict[str, List[TimeSeriesDataFrame]],
|
|
112
|
-
data_per_window: List[TimeSeriesDataFrame],
|
|
113
|
-
time_limit: Optional[int] = None,
|
|
114
|
-
**kwargs,
|
|
115
|
-
):
|
|
116
|
-
if self.eval_metric_seasonal_period is None:
|
|
117
|
-
self.eval_metric_seasonal_period = get_seasonality(self.freq)
|
|
118
|
-
ensemble_selection = TimeSeriesEnsembleSelection(
|
|
119
|
-
ensemble_size=self.ensemble_size,
|
|
120
|
-
metric=self.eval_metric,
|
|
121
|
-
prediction_length=self.prediction_length,
|
|
122
|
-
target=self.target,
|
|
123
|
-
eval_metric_seasonal_period=self.eval_metric_seasonal_period,
|
|
124
|
-
)
|
|
125
|
-
ensemble_selection.fit(
|
|
126
|
-
predictions=list(predictions_per_window.values()),
|
|
127
|
-
labels=data_per_window,
|
|
128
|
-
time_limit=time_limit,
|
|
129
|
-
)
|
|
130
|
-
self.model_to_weight = {}
|
|
131
|
-
for model_name, weight in zip(predictions_per_window.keys(), ensemble_selection.weights_):
|
|
132
|
-
if weight != 0:
|
|
133
|
-
self.model_to_weight[model_name] = weight
|
|
134
|
-
|
|
135
|
-
weights_for_printing = {model: round(weight, 2) for model, weight in self.model_to_weight.items()}
|
|
136
|
-
logger.info(f"\tEnsemble weights: {pprint.pformat(weights_for_printing, width=200)}")
|
|
137
|
-
|
|
138
|
-
@property
|
|
139
|
-
def model_names(self) -> List[str]:
|
|
140
|
-
return list(self.model_to_weight.keys())
|
|
141
|
-
|
|
142
|
-
@property
|
|
143
|
-
def model_weights(self) -> np.ndarray:
|
|
144
|
-
return np.array(list(self.model_to_weight.values()), dtype=np.float64)
|
|
145
|
-
|
|
146
|
-
def predict(self, data: Dict[str, TimeSeriesDataFrame], **kwargs) -> TimeSeriesDataFrame:
|
|
147
|
-
if set(data.keys()) != set(self.model_names):
|
|
148
|
-
raise ValueError(
|
|
149
|
-
f"Set of models given for prediction in {self.name} differ from those provided during initialization."
|
|
150
|
-
)
|
|
151
|
-
for model_name, model_pred in data.items():
|
|
152
|
-
if model_pred is None:
|
|
153
|
-
raise RuntimeError(f"{self.name} cannot predict because base model {model_name} failed.")
|
|
154
|
-
|
|
155
|
-
# Make sure that all predictions have same shape
|
|
156
|
-
assert len(set(pred.shape for pred in data.values())) == 1
|
|
157
|
-
|
|
158
|
-
return sum(data[model_name] * weight for model_name, weight in self.model_to_weight.items())
|
|
159
|
-
|
|
160
|
-
def get_info(self) -> dict:
|
|
161
|
-
info = super().get_info()
|
|
162
|
-
info["model_weights"] = self.model_to_weight
|
|
163
|
-
return info
|
|
164
|
-
|
|
165
|
-
def remap_base_models(self, model_refit_map: Dict[str, str]) -> None:
|
|
166
|
-
updated_weights = {}
|
|
167
|
-
for model, weight in self.model_to_weight.items():
|
|
168
|
-
model_full_name = model_refit_map.get(model, model)
|
|
169
|
-
updated_weights[model_full_name] = weight
|
|
170
|
-
self.model_to_weight = updated_weights
|