autogluon.timeseries 1.2.1b20250205__py3-none-any.whl → 1.2.1b20250207__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.
- autogluon/timeseries/models/abstract/abstract_timeseries_model.py +159 -71
- autogluon/timeseries/models/multi_window/multi_window_model.py +6 -3
- autogluon/timeseries/trainer.py +4 -6
- autogluon/timeseries/version.py +1 -1
- {autogluon.timeseries-1.2.1b20250205.dist-info → autogluon.timeseries-1.2.1b20250207.dist-info}/METADATA +4 -4
- {autogluon.timeseries-1.2.1b20250205.dist-info → autogluon.timeseries-1.2.1b20250207.dist-info}/RECORD +13 -13
- /autogluon.timeseries-1.2.1b20250205-py3.9-nspkg.pth → /autogluon.timeseries-1.2.1b20250207-py3.9-nspkg.pth +0 -0
- {autogluon.timeseries-1.2.1b20250205.dist-info → autogluon.timeseries-1.2.1b20250207.dist-info}/LICENSE +0 -0
- {autogluon.timeseries-1.2.1b20250205.dist-info → autogluon.timeseries-1.2.1b20250207.dist-info}/NOTICE +0 -0
- {autogluon.timeseries-1.2.1b20250205.dist-info → autogluon.timeseries-1.2.1b20250207.dist-info}/WHEEL +0 -0
- {autogluon.timeseries-1.2.1b20250205.dist-info → autogluon.timeseries-1.2.1b20250207.dist-info}/namespace_packages.txt +0 -0
- {autogluon.timeseries-1.2.1b20250205.dist-info → autogluon.timeseries-1.2.1b20250207.dist-info}/top_level.txt +0 -0
- {autogluon.timeseries-1.2.1b20250205.dist-info → autogluon.timeseries-1.2.1b20250207.dist-info}/zip-safe +0 -0
@@ -3,16 +3,19 @@ import os
|
|
3
3
|
import re
|
4
4
|
import time
|
5
5
|
from contextlib import nullcontext
|
6
|
-
from typing import Any, Dict, List, Optional, Tuple, Union
|
6
|
+
from typing import Any, Callable, Dict, List, Optional, Tuple, Union
|
7
7
|
|
8
8
|
import pandas as pd
|
9
|
+
from typing_extensions import Self
|
9
10
|
|
10
11
|
from autogluon.common import space
|
11
12
|
from autogluon.common.loaders import load_pkl
|
12
13
|
from autogluon.common.savers import save_pkl
|
14
|
+
from autogluon.core.constants import AG_ARGS_FIT, REFIT_FULL_SUFFIX
|
13
15
|
from autogluon.core.hpo.exceptions import EmptySearchSpace
|
14
16
|
from autogluon.core.hpo.executors import HpoExecutor, RayHpoExecutor
|
15
17
|
from autogluon.core.models import AbstractModel
|
18
|
+
from autogluon.core.utils.exceptions import TimeLimitExceeded
|
16
19
|
from autogluon.timeseries.dataset import TimeSeriesDataFrame
|
17
20
|
from autogluon.timeseries.metrics import TimeSeriesScorer, check_get_evaluation_metric
|
18
21
|
from autogluon.timeseries.regressor import CovariateRegressor
|
@@ -69,23 +72,9 @@ class AbstractTimeSeriesModel(AbstractModel):
|
|
69
72
|
_covariate_regressor_fit_time_fraction: float = 0.5
|
70
73
|
default_max_time_limit_ratio: float = 0.9
|
71
74
|
|
72
|
-
# TODO:
|
73
|
-
|
74
|
-
|
75
|
-
disk_usage = None # disk / memory size
|
76
|
-
estimate_memory_usage = None
|
77
|
-
reduce_memory_size = None
|
78
|
-
compute_feature_importance = None # feature processing and importance
|
79
|
-
get_features = None
|
80
|
-
_apply_conformalization = None
|
81
|
-
_apply_temperature_scaling = None
|
82
|
-
_predict_proba = None
|
83
|
-
_convert_proba_to_unified_form = None
|
84
|
-
_compute_permutation_importance = None
|
85
|
-
_estimate_memory_usage = None
|
86
|
-
_preprocess = None
|
87
|
-
_preprocess_nonadaptive = None
|
88
|
-
_preprocess_set_features = None
|
75
|
+
# TODO: This is a hack to override the AbstractModel method, which the HPO module
|
76
|
+
# also circumvents with an ugly None-check.
|
77
|
+
estimate_memory_usage: Callable = None # type: ignore
|
89
78
|
|
90
79
|
_supports_known_covariates: bool = False
|
91
80
|
_supports_past_covariates: bool = False
|
@@ -100,7 +89,7 @@ class AbstractTimeSeriesModel(AbstractModel):
|
|
100
89
|
metadata: Optional[CovariateMetadata] = None,
|
101
90
|
eval_metric: Union[str, TimeSeriesScorer, None] = None,
|
102
91
|
eval_metric_seasonal_period: Optional[int] = None,
|
103
|
-
hyperparameters: Dict[str, Union[int, float, str, space.Space]] = None,
|
92
|
+
hyperparameters: Optional[Dict[str, Union[int, float, str, space.Space]]] = None,
|
104
93
|
**kwargs,
|
105
94
|
):
|
106
95
|
name = name or re.sub(r"Model$", "", self.__class__.__name__)
|
@@ -113,13 +102,12 @@ class AbstractTimeSeriesModel(AbstractModel):
|
|
113
102
|
)
|
114
103
|
self.eval_metric: TimeSeriesScorer = check_get_evaluation_metric(eval_metric)
|
115
104
|
self.eval_metric_seasonal_period = eval_metric_seasonal_period
|
116
|
-
self.stopping_metric = None
|
117
105
|
self.problem_type = "timeseries"
|
118
106
|
self.conformalize = False
|
119
107
|
self.target: str = kwargs.get("target", "target")
|
120
108
|
self.metadata = metadata or CovariateMetadata()
|
121
109
|
|
122
|
-
self.freq: str = freq
|
110
|
+
self.freq: Optional[str] = freq
|
123
111
|
self.prediction_length: int = prediction_length
|
124
112
|
self.quantile_levels = kwargs.get("quantile_levels", [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9])
|
125
113
|
|
@@ -143,7 +131,7 @@ class AbstractTimeSeriesModel(AbstractModel):
|
|
143
131
|
def __repr__(self) -> str:
|
144
132
|
return self.name
|
145
133
|
|
146
|
-
def save(self, path: str = None, verbose=True) -> str:
|
134
|
+
def save(self, path: str | None = None, verbose=True) -> str:
|
147
135
|
# Save self._oof_predictions as a separate file, not model attribute
|
148
136
|
if self._oof_predictions is not None:
|
149
137
|
save_pkl.save(
|
@@ -158,9 +146,8 @@ class AbstractTimeSeriesModel(AbstractModel):
|
|
158
146
|
return save_path
|
159
147
|
|
160
148
|
@classmethod
|
161
|
-
def load(
|
162
|
-
|
163
|
-
) -> "AbstractTimeSeriesModel":
|
149
|
+
def load(cls, path: str, reset_paths: bool = True, load_oof: bool = False, verbose: bool = True) -> Self: # type: ignore
|
150
|
+
# TODO: align method signature in new AbstractModel class
|
164
151
|
model = super().load(path=path, reset_paths=reset_paths, verbose=verbose)
|
165
152
|
if load_oof and model._oof_predictions is None:
|
166
153
|
model._oof_predictions = cls.load_oof_predictions(path=path, verbose=verbose)
|
@@ -194,39 +181,62 @@ class AbstractTimeSeriesModel(AbstractModel):
|
|
194
181
|
return self._oof_predictions
|
195
182
|
|
196
183
|
def _get_default_auxiliary_params(self) -> dict:
|
197
|
-
|
198
|
-
|
199
|
-
|
184
|
+
# TODO: refine to values that are absolutely necessary
|
185
|
+
return dict(
|
186
|
+
# Ratio of memory usage allowed by the model. Values > 1.0 have an increased risk of causing OOM errors.
|
187
|
+
# Used in memory checks during model training to avoid OOM errors.
|
188
|
+
max_memory_usage_ratio=1.0,
|
189
|
+
# ratio of given time_limit to use during fit(). If time_limit == 10 and max_time_limit_ratio=0.3,
|
190
|
+
# time_limit would be changed to 3.
|
191
|
+
max_time_limit_ratio=self.default_max_time_limit_ratio,
|
192
|
+
# max time_limit value during fit(). If the provided time_limit is greater than this value, it will be
|
193
|
+
# replaced by max_time_limit. Occurs after max_time_limit_ratio is applied.
|
194
|
+
max_time_limit=None,
|
195
|
+
# min time_limit value during fit(). If the provided time_limit is less than this value, it will be replaced
|
196
|
+
# by min_time_limit. Occurs after max_time_limit is applied.
|
197
|
+
min_time_limit=0,
|
198
|
+
)
|
199
|
+
|
200
|
+
def initialize(self, **kwargs) -> dict:
|
201
|
+
# TODO: remove **kwargs from method signature
|
202
|
+
# TODO: do we even need deferred initialization?
|
203
|
+
|
204
|
+
if not self._is_initialized:
|
205
|
+
self._init_params_aux()
|
206
|
+
self._init_params()
|
207
|
+
self._initialize_transforms()
|
208
|
+
self._is_initialized = True
|
209
|
+
|
210
|
+
# TODO: remove
|
211
|
+
kwargs.pop("feature_metadata", None)
|
212
|
+
kwargs.pop("num_classes", None)
|
213
|
+
|
214
|
+
return kwargs
|
200
215
|
|
201
|
-
def
|
202
|
-
self._init_params_aux()
|
203
|
-
self._init_params()
|
216
|
+
def _initialize_transforms(self) -> None:
|
204
217
|
self.target_scaler = self._create_target_scaler()
|
205
218
|
self.covariate_scaler = self._create_covariate_scaler()
|
206
219
|
self.covariate_regressor = self._create_covariate_regressor()
|
207
220
|
|
208
|
-
def _compute_fit_metadata(self, val_data: TimeSeriesDataFrame = None, **kwargs):
|
209
|
-
fit_metadata = dict(
|
210
|
-
val_in_fit=val_data is not None,
|
211
|
-
)
|
212
|
-
return fit_metadata
|
213
|
-
|
214
|
-
def _validate_fit_memory_usage(self, **kwargs):
|
215
|
-
# memory usage handling not implemented for timeseries models
|
216
|
-
pass
|
217
|
-
|
218
221
|
def get_params(self) -> dict:
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
222
|
+
# TODO: do not extract to AbstractModel if this is only used for getting a
|
223
|
+
# prototype of the object for HPO.
|
224
|
+
hyperparameters = self._user_params.copy()
|
225
|
+
if self._user_params_aux:
|
226
|
+
hyperparameters[AG_ARGS_FIT] = self._user_params_aux.copy()
|
227
|
+
|
228
|
+
return dict(
|
229
|
+
path=self.path_root,
|
230
|
+
name=self.name,
|
231
|
+
problem_type=self.problem_type,
|
232
|
+
eval_metric=self.eval_metric,
|
233
|
+
hyperparameters=hyperparameters,
|
234
|
+
freq=self.freq,
|
235
|
+
prediction_length=self.prediction_length,
|
236
|
+
quantile_levels=self.quantile_levels,
|
237
|
+
metadata=self.metadata,
|
238
|
+
target=self.target,
|
228
239
|
)
|
229
|
-
return params
|
230
240
|
|
231
241
|
def get_info(self) -> dict:
|
232
242
|
"""
|
@@ -247,13 +257,13 @@ class AbstractTimeSeriesModel(AbstractModel):
|
|
247
257
|
}
|
248
258
|
return info
|
249
259
|
|
250
|
-
def fit(
|
260
|
+
def fit( # type: ignore
|
251
261
|
self,
|
252
262
|
train_data: TimeSeriesDataFrame,
|
253
263
|
val_data: Optional[TimeSeriesDataFrame] = None,
|
254
264
|
time_limit: Optional[float] = None,
|
255
265
|
**kwargs,
|
256
|
-
) ->
|
266
|
+
) -> Self:
|
257
267
|
"""Fit timeseries model.
|
258
268
|
|
259
269
|
Models should not override the `fit` method, but instead override the `_fit` method which
|
@@ -287,6 +297,7 @@ class AbstractTimeSeriesModel(AbstractModel):
|
|
287
297
|
model: AbstractTimeSeriesModel
|
288
298
|
The fitted model object
|
289
299
|
"""
|
300
|
+
# TODO: align method signature in new AbstractModel as fit(*args, **kwargs)
|
290
301
|
start_time = time.monotonic()
|
291
302
|
self.initialize(**kwargs)
|
292
303
|
|
@@ -322,7 +333,52 @@ class AbstractTimeSeriesModel(AbstractModel):
|
|
322
333
|
|
323
334
|
if time_limit is not None:
|
324
335
|
time_limit = time_limit - (time.monotonic() - start_time)
|
325
|
-
|
336
|
+
time_limit = self._preprocess_time_limit(time_limit=time_limit)
|
337
|
+
if time_limit <= 0:
|
338
|
+
logger.warning(
|
339
|
+
f"\tWarning: Model has no time left to train, skipping model... (Time Left = {time_limit:.1f}s)"
|
340
|
+
)
|
341
|
+
raise TimeLimitExceeded
|
342
|
+
|
343
|
+
# TODO: disentangle fit_resources computation and validation from tabular logic
|
344
|
+
kwargs = self._preprocess_fit_resources(**kwargs)
|
345
|
+
self.validate_fit_resources(**kwargs)
|
346
|
+
|
347
|
+
self._fit(
|
348
|
+
train_data=train_data,
|
349
|
+
val_data=val_data,
|
350
|
+
time_limit=time_limit,
|
351
|
+
**kwargs,
|
352
|
+
)
|
353
|
+
|
354
|
+
return self
|
355
|
+
|
356
|
+
def _preprocess_time_limit(self, time_limit: float) -> float:
|
357
|
+
original_time_limit = time_limit
|
358
|
+
max_time_limit_ratio = self.params_aux["max_time_limit_ratio"]
|
359
|
+
max_time_limit = self.params_aux["max_time_limit"]
|
360
|
+
min_time_limit = self.params_aux["min_time_limit"]
|
361
|
+
|
362
|
+
time_limit *= max_time_limit_ratio
|
363
|
+
|
364
|
+
if max_time_limit is not None:
|
365
|
+
time_limit = min(time_limit, max_time_limit)
|
366
|
+
|
367
|
+
if min_time_limit is not None:
|
368
|
+
time_limit = max(time_limit, min_time_limit)
|
369
|
+
|
370
|
+
if original_time_limit != time_limit:
|
371
|
+
time_limit_og_str = f"{original_time_limit:.2f}s" if original_time_limit is not None else "None"
|
372
|
+
time_limit_str = f"{time_limit:.2f}s" if time_limit is not None else "None"
|
373
|
+
logger.debug(
|
374
|
+
f"\tTime limit adjusted due to model hyperparameters: "
|
375
|
+
f"{time_limit_og_str} -> {time_limit_str} "
|
376
|
+
f"(ag.max_time_limit={max_time_limit}, "
|
377
|
+
f"ag.max_time_limit_ratio={max_time_limit_ratio}, "
|
378
|
+
f"ag.min_time_limit={min_time_limit})",
|
379
|
+
)
|
380
|
+
|
381
|
+
return time_limit
|
326
382
|
|
327
383
|
@property
|
328
384
|
def allowed_hyperparameters(self) -> List[str]:
|
@@ -380,11 +436,11 @@ class AbstractTimeSeriesModel(AbstractModel):
|
|
380
436
|
else:
|
381
437
|
return None
|
382
438
|
|
383
|
-
def _fit(
|
439
|
+
def _fit( # type: ignore
|
384
440
|
self,
|
385
441
|
train_data: TimeSeriesDataFrame,
|
386
442
|
val_data: Optional[TimeSeriesDataFrame] = None,
|
387
|
-
time_limit: Optional[
|
443
|
+
time_limit: Optional[float] = None,
|
388
444
|
num_cpus: Optional[int] = None,
|
389
445
|
num_gpus: Optional[int] = None,
|
390
446
|
verbosity: int = 2,
|
@@ -394,6 +450,8 @@ class AbstractTimeSeriesModel(AbstractModel):
|
|
394
450
|
the model training logic, `fit` additionally implements other logic such as keeping
|
395
451
|
track of the time limit, etc.
|
396
452
|
"""
|
453
|
+
# TODO: will not be extracted to new AbstractModel
|
454
|
+
|
397
455
|
# TODO: Make the models respect `num_cpus` and `num_gpus` parameters
|
398
456
|
raise NotImplementedError
|
399
457
|
|
@@ -405,7 +463,7 @@ class AbstractTimeSeriesModel(AbstractModel):
|
|
405
463
|
"as hyperparameters when initializing or use `hyperparameter_tune` instead."
|
406
464
|
)
|
407
465
|
|
408
|
-
def predict(
|
466
|
+
def predict( # type: ignore
|
409
467
|
self,
|
410
468
|
data: Union[TimeSeriesDataFrame, Dict[str, Optional[TimeSeriesDataFrame]]],
|
411
469
|
known_covariates: Optional[TimeSeriesDataFrame] = None,
|
@@ -433,6 +491,11 @@ class AbstractTimeSeriesModel(AbstractModel):
|
|
433
491
|
data is given as a separate forecast item in the dictionary, keyed by the `item_id`s
|
434
492
|
of input items.
|
435
493
|
"""
|
494
|
+
# TODO: align method signature in new AbstractModel as predict(*args, **kwargs)
|
495
|
+
|
496
|
+
# TODO: the method signature is not aligned with the model interface in general as it allows dict
|
497
|
+
assert isinstance(data, TimeSeriesDataFrame)
|
498
|
+
|
436
499
|
if self.target_scaler is not None:
|
437
500
|
data = self.target_scaler.fit_transform(data)
|
438
501
|
if self.covariate_scaler is not None:
|
@@ -459,7 +522,9 @@ class AbstractTimeSeriesModel(AbstractModel):
|
|
459
522
|
|
460
523
|
if self.covariate_regressor is not None:
|
461
524
|
if known_covariates is None:
|
462
|
-
known_covariates =
|
525
|
+
known_covariates = TimeSeriesDataFrame.from_data_frame(
|
526
|
+
pd.DataFrame(index=self.get_forecast_horizon_index(data), dtype="float32")
|
527
|
+
)
|
463
528
|
|
464
529
|
predictions = self.covariate_regressor.inverse_transform(
|
465
530
|
predictions,
|
@@ -500,7 +565,7 @@ class AbstractTimeSeriesModel(AbstractModel):
|
|
500
565
|
seasonal_period=self.eval_metric_seasonal_period,
|
501
566
|
)
|
502
567
|
|
503
|
-
def score(self, data: TimeSeriesDataFrame, metric: Optional[str] = None) -> float:
|
568
|
+
def score(self, data: TimeSeriesDataFrame, metric: Optional[str] = None) -> float: # type: ignore
|
504
569
|
"""Return the evaluation scores for given metric and dataset. The last
|
505
570
|
`self.prediction_length` time steps of each time series in the input data set
|
506
571
|
will be held out and used for computing the evaluation score. Time series
|
@@ -526,6 +591,8 @@ class AbstractTimeSeriesModel(AbstractModel):
|
|
526
591
|
The computed forecast evaluation score on the last `self.prediction_length`
|
527
592
|
time steps of each time series.
|
528
593
|
"""
|
594
|
+
# TODO: align method signature in the new AbstractModel
|
595
|
+
|
529
596
|
past_data, known_covariates = data.get_model_inputs_for_scoring(
|
530
597
|
prediction_length=self.prediction_length, known_covariates_names=self.metadata.known_covariates
|
531
598
|
)
|
@@ -577,9 +644,6 @@ class AbstractTimeSeriesModel(AbstractModel):
|
|
577
644
|
|
578
645
|
kwargs = self.initialize(time_limit=time_limit, **kwargs)
|
579
646
|
|
580
|
-
self._register_fit_metadata(**kwargs)
|
581
|
-
self._validate_fit_memory_usage(**kwargs)
|
582
|
-
|
583
647
|
kwargs = self._preprocess_fit_resources(
|
584
648
|
parallel_hpo=hpo_executor.executor_type == "ray", silent=True, **kwargs
|
585
649
|
)
|
@@ -593,22 +657,25 @@ class AbstractTimeSeriesModel(AbstractModel):
|
|
593
657
|
# we use k_fold=1 to circumvent autogluon.core logic to manage resources during parallelization
|
594
658
|
# of different folds
|
595
659
|
hpo_executor.register_resources(self, k_fold=1, **kwargs)
|
596
|
-
return self._hyperparameter_tune(hpo_executor=hpo_executor, **kwargs)
|
597
660
|
|
598
|
-
|
661
|
+
# TODO: Clean up call to _hyperparameter_tune
|
662
|
+
return self._hyperparameter_tune(hpo_executor=hpo_executor, **kwargs) # type: ignore
|
663
|
+
|
664
|
+
def persist(self) -> Self:
|
599
665
|
"""Ask the model to persist its assets in memory, i.e., to predict with low latency. In practice
|
600
666
|
this is used for pretrained models that have to lazy-load model parameters to device memory at
|
601
667
|
prediction time.
|
602
668
|
"""
|
603
669
|
return self
|
604
670
|
|
605
|
-
def _hyperparameter_tune(
|
671
|
+
def _hyperparameter_tune( # type: ignore
|
606
672
|
self,
|
607
673
|
train_data: TimeSeriesDataFrame,
|
608
674
|
val_data: TimeSeriesDataFrame,
|
609
675
|
hpo_executor: HpoExecutor,
|
610
676
|
**kwargs,
|
611
677
|
):
|
678
|
+
# TODO: do not extract to new AbstractModel
|
612
679
|
time_start = time.time()
|
613
680
|
logger.debug(f"\tStarting AbstractTimeSeriesModel hyperparameter tuning for {self.name}")
|
614
681
|
search_space = self._get_search_space()
|
@@ -649,17 +716,27 @@ class AbstractTimeSeriesModel(AbstractModel):
|
|
649
716
|
|
650
717
|
minimum_resources = self.get_minimum_resources(is_gpu_available=self._is_gpu_available())
|
651
718
|
hpo_context = disable_stdout if isinstance(hpo_executor, RayHpoExecutor) else nullcontext
|
719
|
+
|
720
|
+
minimum_cpu_per_trial = minimum_resources.get("num_cpus", 1)
|
721
|
+
if not isinstance(minimum_cpu_per_trial, int):
|
722
|
+
logger.warning(
|
723
|
+
f"Minimum number of CPUs per trial for {self.name} is not an integer. "
|
724
|
+
f"Setting to 1. Minimum number of CPUs per trial: {minimum_cpu_per_trial}"
|
725
|
+
)
|
726
|
+
minimum_cpu_per_trial = 1
|
727
|
+
|
652
728
|
with hpo_context(), warning_filter(): # prevent Ray from outputting its results to stdout with print
|
653
729
|
hpo_executor.execute(
|
654
730
|
model_trial=model_trial,
|
655
731
|
train_fn_kwargs=train_fn_kwargs,
|
656
732
|
directory=directory,
|
657
|
-
minimum_cpu_per_trial=
|
733
|
+
minimum_cpu_per_trial=minimum_cpu_per_trial,
|
658
734
|
minimum_gpu_per_trial=minimum_resources.get("num_gpus", 0),
|
659
|
-
model_estimate_memory_usage=model_estimate_memory_usage,
|
735
|
+
model_estimate_memory_usage=model_estimate_memory_usage, # type: ignore
|
660
736
|
adapter_type="timeseries",
|
661
737
|
)
|
662
738
|
|
739
|
+
assert self.path_root is not None
|
663
740
|
hpo_models, analysis = hpo_executor.get_hpo_results(
|
664
741
|
model_name=self.name,
|
665
742
|
model_path_root=self.path_root,
|
@@ -668,7 +745,7 @@ class AbstractTimeSeriesModel(AbstractModel):
|
|
668
745
|
|
669
746
|
return hpo_models, analysis
|
670
747
|
|
671
|
-
def preprocess(
|
748
|
+
def preprocess( # type: ignore
|
672
749
|
self,
|
673
750
|
data: TimeSeriesDataFrame,
|
674
751
|
known_covariates: Optional[TimeSeriesDataFrame] = None,
|
@@ -676,15 +753,26 @@ class AbstractTimeSeriesModel(AbstractModel):
|
|
676
753
|
**kwargs,
|
677
754
|
) -> Tuple[TimeSeriesDataFrame, Optional[TimeSeriesDataFrame]]:
|
678
755
|
"""Method that implements model-specific preprocessing logic."""
|
756
|
+
# TODO: move to new AbstractModel
|
679
757
|
return data, known_covariates
|
680
758
|
|
681
|
-
def get_memory_size(self,
|
759
|
+
def get_memory_size(self, allow_exception: bool = False) -> Optional[int]:
|
760
|
+
# TODO: move to new AbstractModel
|
682
761
|
return None
|
683
762
|
|
684
|
-
def convert_to_refit_full_via_copy(self) ->
|
685
|
-
|
763
|
+
def convert_to_refit_full_via_copy(self) -> Self:
|
764
|
+
# save the model as a new model on disk
|
765
|
+
previous_name = self.name
|
766
|
+
self.rename(self.name + REFIT_FULL_SUFFIX)
|
767
|
+
refit_model_path = self.path
|
768
|
+
self.save(path=self.path, verbose=False)
|
769
|
+
|
770
|
+
self.rename(previous_name)
|
771
|
+
|
772
|
+
refit_model = self.load(path=refit_model_path, verbose=False)
|
686
773
|
refit_model.val_score = None
|
687
774
|
refit_model.predict_time = None
|
775
|
+
|
688
776
|
return refit_model
|
689
777
|
|
690
778
|
def get_user_params(self) -> dict:
|
@@ -218,11 +218,14 @@ class MultiWindowBacktestingModel(AbstractTimeSeriesModel):
|
|
218
218
|
def _get_search_space(self):
|
219
219
|
return self.model_base._get_search_space()
|
220
220
|
|
221
|
-
def
|
222
|
-
self._init_params_aux()
|
223
|
-
self._init_params()
|
221
|
+
def _initialize_covariate_regressor_scaler(self, **kwargs) -> None:
|
224
222
|
# Do not initialize the target_scaler and covariate_regressor in the multi window model!
|
223
|
+
pass
|
224
|
+
|
225
|
+
def initialize(self, **kwargs) -> dict:
|
226
|
+
super().initialize(**kwargs)
|
225
227
|
self.model_base.initialize(**kwargs)
|
228
|
+
return kwargs
|
226
229
|
|
227
230
|
def _get_hpo_train_fn_kwargs(self, **train_fn_kwargs) -> dict:
|
228
231
|
train_fn_kwargs["is_bagged_model"] = True
|
autogluon/timeseries/trainer.py
CHANGED
@@ -208,7 +208,7 @@ class TimeSeriesTrainer(AbstractTrainer[AbstractTimeSeriesModel]):
|
|
208
208
|
results[model] = self.model_graph.nodes[model][attribute]
|
209
209
|
return results
|
210
210
|
|
211
|
-
def get_model_best(self
|
211
|
+
def get_model_best(self) -> str:
|
212
212
|
"""Return the name of the best model by model performance on the validation set."""
|
213
213
|
models = self.get_model_names()
|
214
214
|
if not models:
|
@@ -231,13 +231,13 @@ class TimeSeriesTrainer(AbstractTrainer[AbstractTimeSeriesModel]):
|
|
231
231
|
key=lambda mns: (mns[1], -mns[2]), # (score, -level)
|
232
232
|
)[0]
|
233
233
|
|
234
|
-
def get_model_names(self, level: Optional[int] = None
|
234
|
+
def get_model_names(self, level: Optional[int] = None) -> List[str]:
|
235
235
|
"""Get model names that are registered in the model graph"""
|
236
236
|
if level is not None:
|
237
237
|
return list(node for node, l in self._get_model_levels().items() if l == level) # noqa: E741
|
238
238
|
return list(self.model_graph.nodes)
|
239
239
|
|
240
|
-
def get_info(self, include_model_info: bool = False
|
240
|
+
def get_info(self, include_model_info: bool = False) -> Dict[str, Any]:
|
241
241
|
num_models_trained = len(self.get_model_names())
|
242
242
|
if self.model_best is not None:
|
243
243
|
best_model = self.model_best
|
@@ -694,7 +694,7 @@ class TimeSeriesTrainer(AbstractTrainer[AbstractTimeSeriesModel]):
|
|
694
694
|
return df[explicit_column_order]
|
695
695
|
|
696
696
|
def persist(
|
697
|
-
self, model_names: Union[Literal["all", "best"], List[str]] = "all", with_ancestors: bool = False
|
697
|
+
self, model_names: Union[Literal["all", "best"], List[str]] = "all", with_ancestors: bool = False
|
698
698
|
) -> List[str]:
|
699
699
|
if model_names == "all":
|
700
700
|
model_names = self.get_model_names()
|
@@ -761,7 +761,6 @@ class TimeSeriesTrainer(AbstractTrainer[AbstractTimeSeriesModel]):
|
|
761
761
|
model: Optional[Union[str, AbstractTimeSeriesModel]] = None,
|
762
762
|
use_cache: bool = True,
|
763
763
|
random_seed: Optional[int] = None,
|
764
|
-
**kwargs,
|
765
764
|
) -> TimeSeriesDataFrame:
|
766
765
|
model_name = self._get_model_for_prediction(model)
|
767
766
|
model_pred_dict, _ = self.get_model_pred_dict(
|
@@ -1240,7 +1239,6 @@ class TimeSeriesTrainer(AbstractTrainer[AbstractTimeSeriesModel]):
|
|
1240
1239
|
freq: Optional[str] = None,
|
1241
1240
|
excluded_model_types: Optional[List[str]] = None,
|
1242
1241
|
hyperparameter_tune: bool = False,
|
1243
|
-
**kwargs,
|
1244
1242
|
) -> List[AbstractTimeSeriesModel]:
|
1245
1243
|
return get_preset_models(
|
1246
1244
|
path=self.path,
|
autogluon/timeseries/version.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: autogluon.timeseries
|
3
|
-
Version: 1.2.
|
3
|
+
Version: 1.2.1b20250207
|
4
4
|
Summary: Fast and Accurate ML in 3 Lines of Code
|
5
5
|
Home-page: https://github.com/autogluon/autogluon
|
6
6
|
Author: AutoGluon Community
|
@@ -55,9 +55,9 @@ Requires-Dist: fugue>=0.9.0
|
|
55
55
|
Requires-Dist: tqdm<5,>=4.38
|
56
56
|
Requires-Dist: orjson~=3.9
|
57
57
|
Requires-Dist: tensorboard<3,>=2.9
|
58
|
-
Requires-Dist: autogluon.core[raytune]==1.2.
|
59
|
-
Requires-Dist: autogluon.common==1.2.
|
60
|
-
Requires-Dist: autogluon.tabular[catboost,lightgbm,xgboost]==1.2.
|
58
|
+
Requires-Dist: autogluon.core[raytune]==1.2.1b20250207
|
59
|
+
Requires-Dist: autogluon.common==1.2.1b20250207
|
60
|
+
Requires-Dist: autogluon.tabular[catboost,lightgbm,xgboost]==1.2.1b20250207
|
61
61
|
Provides-Extra: all
|
62
62
|
Provides-Extra: chronos-onnx
|
63
63
|
Requires-Dist: optimum[onnxruntime]<1.20,>=1.17; extra == "chronos-onnx"
|
@@ -1,12 +1,12 @@
|
|
1
|
-
autogluon.timeseries-1.2.
|
1
|
+
autogluon.timeseries-1.2.1b20250207-py3.9-nspkg.pth,sha256=cQGwpuGPqg1GXscIwt-7PmME1OnSpD-7ixkikJ31WAY,554
|
2
2
|
autogluon/timeseries/__init__.py,sha256=_CrLLc1fkjen7UzWoO0Os8WZoHOgvZbHKy46I8v_4k4,304
|
3
3
|
autogluon/timeseries/evaluator.py,sha256=l642tYfTHsl8WVIq_vV6qhgAFVFr9UuZD7gLra3A_Kc,250
|
4
4
|
autogluon/timeseries/learner.py,sha256=PDAHFlos6q5JukwRE86tKoH0zxYf3nLzy7qfD_a5NYY,13849
|
5
5
|
autogluon/timeseries/predictor.py,sha256=HTE8a_R_9U0z-KlxyoELm-64BXNRzFu3mIEbTabQNEc,85171
|
6
6
|
autogluon/timeseries/regressor.py,sha256=dIXttb0SOGS8IAwZOMANNDc796spN0LMysGUvuKgskU,9623
|
7
7
|
autogluon/timeseries/splitter.py,sha256=yzPca9p2bWV-_VJAptUyyzQsxu-uixAdpMoGQtDzMD4,3205
|
8
|
-
autogluon/timeseries/trainer.py,sha256=
|
9
|
-
autogluon/timeseries/version.py,sha256=
|
8
|
+
autogluon/timeseries/trainer.py,sha256=L9FT5qERcqlWTgH9IgE6QsO0aBNj2nivRKF2Oy4UJOk,57250
|
9
|
+
autogluon/timeseries/version.py,sha256=qLGkaeRkK6Ci2vuuzx2wJyC_Bqxje0rKtsrMZLKB_A4,91
|
10
10
|
autogluon/timeseries/configs/__init__.py,sha256=BTtHIPCYeGjqgOcvqb8qPD4VNX-ICKOg6wnkew1cPOE,98
|
11
11
|
autogluon/timeseries/configs/presets_configs.py,sha256=cLat8ecLlWrI-SC5KLBDCX2SbVXaucemy2pjxJAtSY0,2543
|
12
12
|
autogluon/timeseries/dataset/__init__.py,sha256=UvnhAN5tjgxXTHoZMQDy64YMDj4Xxa68yY7NP4vAw0o,81
|
@@ -19,7 +19,7 @@ autogluon/timeseries/metrics/utils.py,sha256=HuDe1BNe8yJU4f_DKM913nNrUueoRaw6zhx
|
|
19
19
|
autogluon/timeseries/models/__init__.py,sha256=MYD9JJ-wUDE5B6jW6E6LU2eXQ6vflfQBvqQJkdzJa3A,1189
|
20
20
|
autogluon/timeseries/models/presets.py,sha256=dEjdRgd1WhtjUK2LRkLnc05cBamz3mwzaX4PV58EzKg,12472
|
21
21
|
autogluon/timeseries/models/abstract/__init__.py,sha256=wvDsQAZIV0N3AwBeMaGItoQ82trEfnT-nol2AAOIxBg,102
|
22
|
-
autogluon/timeseries/models/abstract/abstract_timeseries_model.py,sha256=
|
22
|
+
autogluon/timeseries/models/abstract/abstract_timeseries_model.py,sha256=pUWU45mFl-mbNisf85jMlllz_Qfnq0m-DTUbtlRaBN4,35682
|
23
23
|
autogluon/timeseries/models/abstract/model_trial.py,sha256=ENPg_7nsdxIvaNM0o0UShZ3x8jFlRmwRc5m0fGPC0TM,3720
|
24
24
|
autogluon/timeseries/models/autogluon_tabular/__init__.py,sha256=r9i6jWcyeLHYClkcMSKRVsfrkBUMxpDrTATNTBc_qgQ,136
|
25
25
|
autogluon/timeseries/models/autogluon_tabular/mlforecast.py,sha256=H2UlpnJcIIEi_swYn9AJUPFGT4qwFSmzZ7yvC3I2pUU,33039
|
@@ -45,7 +45,7 @@ autogluon/timeseries/models/local/naive.py,sha256=iwRcFMFmJKPWPbD9TWaIUS51oav69F
|
|
45
45
|
autogluon/timeseries/models/local/npts.py,sha256=Bp74doKnfpGE8ywP4FWOCI_RwRMsmgocYDfGtq764DA,4143
|
46
46
|
autogluon/timeseries/models/local/statsforecast.py,sha256=Rp3pwjs0t8VXiUhxgVUKLme52Br3sbg675N0_O-SIU8,32441
|
47
47
|
autogluon/timeseries/models/multi_window/__init__.py,sha256=Bq7AT2Jxdd4WNqmjTdzeqgNiwn1NCyWp4tBIWaM-zfI,60
|
48
|
-
autogluon/timeseries/models/multi_window/multi_window_model.py,sha256=
|
48
|
+
autogluon/timeseries/models/multi_window/multi_window_model.py,sha256=kVHAGNQC8ahEmAgnnLa38hcbxMFC_Tl1lHFJMos2G8w,11985
|
49
49
|
autogluon/timeseries/transforms/__init__.py,sha256=Stym_998LZQgKPuFN4_w1AcJFh4_AeaQLXgXLzv53kY,299
|
50
50
|
autogluon/timeseries/transforms/covariate_scaler.py,sha256=Xa1qBKAMt8TRDEeTcc4Gtym1iXt2_Yat8gwQQV6lIFs,7013
|
51
51
|
autogluon/timeseries/transforms/target_scaler.py,sha256=R-PhcaXTTRkl4bkguSy7p2QU7Grv2-ew3QsNT4NJv-I,5382
|
@@ -58,11 +58,11 @@ autogluon/timeseries/utils/datetime/base.py,sha256=3NdsH3NDq4cVAOSoy3XpaNixyNlbj
|
|
58
58
|
autogluon/timeseries/utils/datetime/lags.py,sha256=gQDk5_zmsY5DUWDUpSaCKYkQ9nHKKY-LsywJQRAoYSk,5988
|
59
59
|
autogluon/timeseries/utils/datetime/seasonality.py,sha256=YK_2k8hvYIMW-sJPnjGWRtCnvIOthwA2hATB3nwVoD4,834
|
60
60
|
autogluon/timeseries/utils/datetime/time_features.py,sha256=MjLi3zQ00uWWJtXH9oGX2GJkTbvjdSiuabSa4kcVuxE,2672
|
61
|
-
autogluon.timeseries-1.2.
|
62
|
-
autogluon.timeseries-1.2.
|
63
|
-
autogluon.timeseries-1.2.
|
64
|
-
autogluon.timeseries-1.2.
|
65
|
-
autogluon.timeseries-1.2.
|
66
|
-
autogluon.timeseries-1.2.
|
67
|
-
autogluon.timeseries-1.2.
|
68
|
-
autogluon.timeseries-1.2.
|
61
|
+
autogluon.timeseries-1.2.1b20250207.dist-info/LICENSE,sha256=CeipvOyAZxBGUsFoaFqwkx54aPnIKEtm9a5u2uXxEws,10142
|
62
|
+
autogluon.timeseries-1.2.1b20250207.dist-info/METADATA,sha256=nv2ILn9mLStJRGzSOzJxsE7qdRZOgECZtX5A_dYIs_Y,12662
|
63
|
+
autogluon.timeseries-1.2.1b20250207.dist-info/NOTICE,sha256=7nPQuj8Kp-uXsU0S5so3-2dNU5EctS5hDXvvzzehd7E,114
|
64
|
+
autogluon.timeseries-1.2.1b20250207.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
|
65
|
+
autogluon.timeseries-1.2.1b20250207.dist-info/namespace_packages.txt,sha256=giERA4R78OkJf2ijn5slgjURlhRPzfLr7waIcGkzYAo,10
|
66
|
+
autogluon.timeseries-1.2.1b20250207.dist-info/top_level.txt,sha256=giERA4R78OkJf2ijn5slgjURlhRPzfLr7waIcGkzYAo,10
|
67
|
+
autogluon.timeseries-1.2.1b20250207.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
68
|
+
autogluon.timeseries-1.2.1b20250207.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|