autogluon.timeseries 1.4.1b20250827__py3-none-any.whl → 1.4.1b20250903__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/metrics/abstract.py +2 -3
- autogluon/timeseries/models/multi_window/multi_window_model.py +29 -18
- autogluon/timeseries/trainer/prediction_cache.py +149 -0
- autogluon/timeseries/trainer/trainer.py +13 -69
- autogluon/timeseries/utils/features.py +1 -1
- autogluon/timeseries/version.py +1 -1
- {autogluon.timeseries-1.4.1b20250827.dist-info → autogluon.timeseries-1.4.1b20250903.dist-info}/METADATA +5 -5
- {autogluon.timeseries-1.4.1b20250827.dist-info → autogluon.timeseries-1.4.1b20250903.dist-info}/RECORD +15 -14
- /autogluon.timeseries-1.4.1b20250827-py3.9-nspkg.pth → /autogluon.timeseries-1.4.1b20250903-py3.9-nspkg.pth +0 -0
- {autogluon.timeseries-1.4.1b20250827.dist-info → autogluon.timeseries-1.4.1b20250903.dist-info}/LICENSE +0 -0
- {autogluon.timeseries-1.4.1b20250827.dist-info → autogluon.timeseries-1.4.1b20250903.dist-info}/NOTICE +0 -0
- {autogluon.timeseries-1.4.1b20250827.dist-info → autogluon.timeseries-1.4.1b20250903.dist-info}/WHEEL +0 -0
- {autogluon.timeseries-1.4.1b20250827.dist-info → autogluon.timeseries-1.4.1b20250903.dist-info}/namespace_packages.txt +0 -0
- {autogluon.timeseries-1.4.1b20250827.dist-info → autogluon.timeseries-1.4.1b20250903.dist-info}/top_level.txt +0 -0
- {autogluon.timeseries-1.4.1b20250827.dist-info → autogluon.timeseries-1.4.1b20250903.dist-info}/zip-safe +0 -0
@@ -2,7 +2,6 @@ import warnings
|
|
2
2
|
from typing import Optional, Sequence, Union, overload
|
3
3
|
|
4
4
|
import numpy as np
|
5
|
-
import numpy.typing as npt
|
6
5
|
import pandas as pd
|
7
6
|
|
8
7
|
from autogluon.timeseries import TimeSeriesDataFrame
|
@@ -242,12 +241,12 @@ class TimeSeriesScorer:
|
|
242
241
|
@staticmethod
|
243
242
|
def check_get_horizon_weight(
|
244
243
|
horizon_weight: Union[Sequence[float], np.ndarray], prediction_length: int
|
245
|
-
) ->
|
244
|
+
) -> np.ndarray: ...
|
246
245
|
|
247
246
|
@staticmethod
|
248
247
|
def check_get_horizon_weight(
|
249
248
|
horizon_weight: Union[Sequence[float], np.ndarray, None], prediction_length: int
|
250
|
-
) -> Optional[
|
249
|
+
) -> Optional[np.ndarray]:
|
251
250
|
"""Convert horizon_weight to a non-negative numpy array that sums up to prediction_length.
|
252
251
|
Raises an exception if horizon_weight has an invalid shape or contains invalid values.
|
253
252
|
|
@@ -7,6 +7,7 @@ import time
|
|
7
7
|
from typing import Any, Optional, Type, Union
|
8
8
|
|
9
9
|
import numpy as np
|
10
|
+
from typing_extensions import Self
|
10
11
|
|
11
12
|
import autogluon.core as ag
|
12
13
|
from autogluon.timeseries.dataset.ts_dataframe import TimeSeriesDataFrame
|
@@ -73,10 +74,6 @@ class MultiWindowBacktestingModel(AbstractTimeSeriesModel):
|
|
73
74
|
def supports_past_covariates(self) -> bool:
|
74
75
|
return self.model_base.supports_past_covariates
|
75
76
|
|
76
|
-
@property
|
77
|
-
def supports_cat_covariates(self) -> bool:
|
78
|
-
return self.model_base.supports_cat_covariates
|
79
|
-
|
80
77
|
def _get_model_base(self):
|
81
78
|
return self.model_base
|
82
79
|
|
@@ -86,15 +83,18 @@ class MultiWindowBacktestingModel(AbstractTimeSeriesModel):
|
|
86
83
|
def _is_gpu_available(self) -> bool:
|
87
84
|
return self._get_model_base()._is_gpu_available()
|
88
85
|
|
89
|
-
def get_minimum_resources(self, is_gpu_available: bool = False) ->
|
86
|
+
def get_minimum_resources(self, is_gpu_available: bool = False) -> dict[str, Union[int, float]]:
|
90
87
|
return self._get_model_base().get_minimum_resources(is_gpu_available)
|
91
88
|
|
92
89
|
def _fit(
|
93
90
|
self,
|
94
91
|
train_data: TimeSeriesDataFrame,
|
95
92
|
val_data: Optional[TimeSeriesDataFrame] = None,
|
96
|
-
time_limit: Optional[
|
97
|
-
|
93
|
+
time_limit: Optional[float] = None,
|
94
|
+
num_cpus: Optional[int] = None,
|
95
|
+
num_gpus: Optional[int] = None,
|
96
|
+
verbosity: int = 2,
|
97
|
+
val_splitter: Optional[AbstractWindowSplitter] = None,
|
98
98
|
refit_every_n_windows: Optional[int] = 1,
|
99
99
|
**kwargs,
|
100
100
|
):
|
@@ -111,11 +111,15 @@ class MultiWindowBacktestingModel(AbstractTimeSeriesModel):
|
|
111
111
|
|
112
112
|
oof_predictions_per_window = []
|
113
113
|
global_fit_start_time = time.time()
|
114
|
+
model: Optional[AbstractTimeSeriesModel] = None
|
114
115
|
|
115
116
|
for window_index, (train_fold, val_fold) in enumerate(val_splitter.split(train_data)):
|
116
117
|
logger.debug(f"\tWindow {window_index}")
|
118
|
+
|
117
119
|
# refit_this_window is always True for the 0th window
|
118
120
|
refit_this_window = window_index % refit_every_n_windows == 0
|
121
|
+
assert window_index != 0 or refit_this_window
|
122
|
+
|
119
123
|
if time_limit is None:
|
120
124
|
time_left_for_window = None
|
121
125
|
else:
|
@@ -148,6 +152,7 @@ class MultiWindowBacktestingModel(AbstractTimeSeriesModel):
|
|
148
152
|
else:
|
149
153
|
time_left_for_prediction = time_limit - (time.time() - global_fit_start_time)
|
150
154
|
|
155
|
+
assert model is not None
|
151
156
|
model.score_and_cache_oof(
|
152
157
|
val_fold, store_val_score=True, store_predict_time=True, time_limit=time_left_for_prediction
|
153
158
|
)
|
@@ -172,11 +177,13 @@ class MultiWindowBacktestingModel(AbstractTimeSeriesModel):
|
|
172
177
|
|
173
178
|
# Only the model trained on most recent data is saved & used for prediction
|
174
179
|
self.most_recent_model = model
|
175
|
-
self.
|
180
|
+
assert self.most_recent_model is not None
|
181
|
+
|
182
|
+
self.most_recent_model_folder = most_recent_refit_window # type: ignore
|
176
183
|
self.predict_time = self.most_recent_model.predict_time
|
177
|
-
self.fit_time = time.time() - global_fit_start_time - self.predict_time
|
184
|
+
self.fit_time = time.time() - global_fit_start_time - self.predict_time # type: ignore
|
178
185
|
self._oof_predictions = oof_predictions_per_window
|
179
|
-
self.val_score = np.mean([info["val_score"] for info in self.info_per_val_window])
|
186
|
+
self.val_score = np.mean([info["val_score"] for info in self.info_per_val_window]) # type: ignore
|
180
187
|
|
181
188
|
def get_info(self) -> dict:
|
182
189
|
info = super().get_info()
|
@@ -227,7 +234,7 @@ class MultiWindowBacktestingModel(AbstractTimeSeriesModel):
|
|
227
234
|
train_fn_kwargs["init_params"]["model_base_kwargs"] = self.get_params()
|
228
235
|
return train_fn_kwargs
|
229
236
|
|
230
|
-
def save(self, path: str = None, verbose=True) -> str:
|
237
|
+
def save(self, path: Optional[str] = None, verbose: bool = True) -> str:
|
231
238
|
most_recent_model = self.most_recent_model
|
232
239
|
self.most_recent_model = None
|
233
240
|
save_path = super().save(path, verbose)
|
@@ -238,32 +245,36 @@ class MultiWindowBacktestingModel(AbstractTimeSeriesModel):
|
|
238
245
|
most_recent_model.save()
|
239
246
|
return save_path
|
240
247
|
|
241
|
-
def persist(self):
|
248
|
+
def persist(self) -> Self:
|
242
249
|
if self.most_recent_model is None:
|
243
250
|
raise ValueError(f"{self.name} must be fit before persisting")
|
244
251
|
self.most_recent_model.persist()
|
252
|
+
return self
|
245
253
|
|
246
254
|
@classmethod
|
247
255
|
def load(
|
248
256
|
cls, path: str, reset_paths: bool = True, load_oof: bool = False, verbose: bool = True
|
249
257
|
) -> AbstractTimeSeriesModel:
|
250
258
|
model = super().load(path=path, reset_paths=reset_paths, load_oof=load_oof, verbose=verbose)
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
259
|
+
if model.most_recent_model_folder is not None:
|
260
|
+
most_recent_model_path = os.path.join(model.path, model.most_recent_model_folder)
|
261
|
+
model.most_recent_model = model.model_base_type.load(
|
262
|
+
most_recent_model_path,
|
263
|
+
reset_paths=reset_paths,
|
264
|
+
verbose=verbose,
|
265
|
+
)
|
257
266
|
return model
|
258
267
|
|
259
268
|
def convert_to_refit_full_template(self) -> AbstractTimeSeriesModel:
|
260
269
|
# refit_model is an instance of base model type, not MultiWindowBacktestingModel
|
270
|
+
assert self.most_recent_model is not None, "Most recent model is None. Model must be fit first."
|
261
271
|
refit_model = self.most_recent_model.convert_to_refit_full_template()
|
262
272
|
refit_model.rename(self.name + ag.constants.REFIT_FULL_SUFFIX)
|
263
273
|
return refit_model
|
264
274
|
|
265
275
|
def convert_to_refit_full_via_copy(self) -> AbstractTimeSeriesModel:
|
266
276
|
# refit_model is an instance of base model type, not MultiWindowBacktestingModel
|
277
|
+
assert self.most_recent_model is not None, "Most recent model is None. Model must be fit first."
|
267
278
|
refit_model = self.most_recent_model.convert_to_refit_full_via_copy()
|
268
279
|
refit_model.rename(self.name + ag.constants.REFIT_FULL_SUFFIX)
|
269
280
|
return refit_model
|
@@ -0,0 +1,149 @@
|
|
1
|
+
import logging
|
2
|
+
from abc import ABC, abstractmethod
|
3
|
+
from pathlib import Path
|
4
|
+
from typing import Any, Optional
|
5
|
+
|
6
|
+
from autogluon.common.utils.utils import hash_pandas_df
|
7
|
+
from autogluon.core.utils.loaders import load_pkl
|
8
|
+
from autogluon.core.utils.savers import save_pkl
|
9
|
+
from autogluon.timeseries import TimeSeriesDataFrame
|
10
|
+
|
11
|
+
logger = logging.getLogger(__name__)
|
12
|
+
|
13
|
+
|
14
|
+
class PredictionCache(ABC):
|
15
|
+
"""A prediction cache is an abstract key-value store for time series predictions. The storage is keyed by
|
16
|
+
(data, known_covariates) pairs and stores (model_pred_dict, pred_time_dict) pair values. In this stored pair,
|
17
|
+
(model_pred_dict, pred_time_dict), both dictionaries are keyed by model names.
|
18
|
+
"""
|
19
|
+
|
20
|
+
def __init__(self, root_path: str):
|
21
|
+
self.root_path = Path(root_path)
|
22
|
+
|
23
|
+
@abstractmethod
|
24
|
+
def get(
|
25
|
+
self, data: TimeSeriesDataFrame, known_covariates: Optional[TimeSeriesDataFrame]
|
26
|
+
) -> tuple[dict[str, Optional[TimeSeriesDataFrame]], dict[str, float]]:
|
27
|
+
pass
|
28
|
+
|
29
|
+
@abstractmethod
|
30
|
+
def put(
|
31
|
+
self,
|
32
|
+
data: TimeSeriesDataFrame,
|
33
|
+
known_covariates: Optional[TimeSeriesDataFrame],
|
34
|
+
model_pred_dict: dict[str, Optional[TimeSeriesDataFrame]],
|
35
|
+
pred_time_dict: dict[str, float],
|
36
|
+
) -> None:
|
37
|
+
pass
|
38
|
+
|
39
|
+
@abstractmethod
|
40
|
+
def clear(self) -> None:
|
41
|
+
pass
|
42
|
+
|
43
|
+
|
44
|
+
def get_prediction_cache(use_cache: bool, root_path: str) -> PredictionCache:
|
45
|
+
if use_cache:
|
46
|
+
return FileBasedPredictionCache(root_path=root_path)
|
47
|
+
else:
|
48
|
+
return NoOpPredictionCache(root_path=root_path)
|
49
|
+
|
50
|
+
|
51
|
+
def compute_dataset_hash(data: TimeSeriesDataFrame, known_covariates: Optional[TimeSeriesDataFrame] = None) -> str:
|
52
|
+
"""Compute a unique string that identifies the time series dataset."""
|
53
|
+
combined_hash = hash_pandas_df(data) + hash_pandas_df(known_covariates) + hash_pandas_df(data.static_features)
|
54
|
+
return combined_hash
|
55
|
+
|
56
|
+
|
57
|
+
class NoOpPredictionCache(PredictionCache):
|
58
|
+
"""A dummy (no-op) prediction cache."""
|
59
|
+
|
60
|
+
def get(
|
61
|
+
self, data: TimeSeriesDataFrame, known_covariates: Optional[TimeSeriesDataFrame]
|
62
|
+
) -> tuple[dict[str, Optional[TimeSeriesDataFrame]], dict[str, float]]:
|
63
|
+
return {}, {}
|
64
|
+
|
65
|
+
def put(
|
66
|
+
self,
|
67
|
+
data: TimeSeriesDataFrame,
|
68
|
+
known_covariates: Optional[TimeSeriesDataFrame],
|
69
|
+
model_pred_dict: dict[str, Optional[TimeSeriesDataFrame]],
|
70
|
+
pred_time_dict: dict[str, float],
|
71
|
+
) -> None:
|
72
|
+
pass
|
73
|
+
|
74
|
+
def clear(self) -> None:
|
75
|
+
pass
|
76
|
+
|
77
|
+
|
78
|
+
class FileBasedPredictionCache(PredictionCache):
|
79
|
+
"""A file-backed cache of model predictions."""
|
80
|
+
|
81
|
+
_cached_predictions_filename = "cached_predictions.pkl"
|
82
|
+
|
83
|
+
@property
|
84
|
+
def path(self) -> Path:
|
85
|
+
return Path(self.root_path) / self._cached_predictions_filename
|
86
|
+
|
87
|
+
def get(
|
88
|
+
self, data: TimeSeriesDataFrame, known_covariates: Optional[TimeSeriesDataFrame]
|
89
|
+
) -> tuple[dict[str, Optional[TimeSeriesDataFrame]], dict[str, float]]:
|
90
|
+
dataset_hash = compute_dataset_hash(data, known_covariates)
|
91
|
+
return self._get_cached_pred_dicts(dataset_hash)
|
92
|
+
|
93
|
+
def put(
|
94
|
+
self,
|
95
|
+
data: TimeSeriesDataFrame,
|
96
|
+
known_covariates: Optional[TimeSeriesDataFrame],
|
97
|
+
model_pred_dict: dict[str, Optional[TimeSeriesDataFrame]],
|
98
|
+
pred_time_dict: dict[str, float],
|
99
|
+
) -> None:
|
100
|
+
dataset_hash = compute_dataset_hash(data, known_covariates)
|
101
|
+
self._save_cached_pred_dicts(dataset_hash, model_pred_dict, pred_time_dict)
|
102
|
+
|
103
|
+
def clear(self) -> None:
|
104
|
+
if self.path.exists():
|
105
|
+
logger.debug(f"Removing existing cached predictions file {self.path}")
|
106
|
+
self.path.unlink()
|
107
|
+
|
108
|
+
def _load_cached_predictions(self) -> dict[str, dict[str, dict[str, Any]]]:
|
109
|
+
if self.path.exists():
|
110
|
+
try:
|
111
|
+
cached_predictions = load_pkl.load(str(self.path))
|
112
|
+
except Exception:
|
113
|
+
cached_predictions = {}
|
114
|
+
else:
|
115
|
+
cached_predictions = {}
|
116
|
+
return cached_predictions
|
117
|
+
|
118
|
+
def _get_cached_pred_dicts(
|
119
|
+
self, dataset_hash: str
|
120
|
+
) -> tuple[dict[str, Optional[TimeSeriesDataFrame]], dict[str, float]]:
|
121
|
+
"""Load cached predictions for given dataset_hash from disk, if possible.
|
122
|
+
|
123
|
+
If loading fails for any reason, empty dicts are returned.
|
124
|
+
"""
|
125
|
+
cached_predictions = self._load_cached_predictions()
|
126
|
+
if dataset_hash in cached_predictions:
|
127
|
+
try:
|
128
|
+
model_pred_dict = cached_predictions[dataset_hash]["model_pred_dict"]
|
129
|
+
pred_time_dict = cached_predictions[dataset_hash]["pred_time_dict"]
|
130
|
+
assert model_pred_dict.keys() == pred_time_dict.keys()
|
131
|
+
return model_pred_dict, pred_time_dict
|
132
|
+
except Exception:
|
133
|
+
logger.warning("Cached predictions are corrupted. Predictions will be made from scratch.")
|
134
|
+
return {}, {}
|
135
|
+
|
136
|
+
def _save_cached_pred_dicts(
|
137
|
+
self,
|
138
|
+
dataset_hash: str,
|
139
|
+
model_pred_dict: dict[str, Optional[TimeSeriesDataFrame]],
|
140
|
+
pred_time_dict: dict[str, float],
|
141
|
+
) -> None:
|
142
|
+
cached_predictions = self._load_cached_predictions()
|
143
|
+
# Do not save results for models that failed
|
144
|
+
cached_predictions[dataset_hash] = {
|
145
|
+
"model_pred_dict": {k: v for k, v in model_pred_dict.items() if v is not None},
|
146
|
+
"pred_time_dict": {k: v for k, v in pred_time_dict.items() if v is not None},
|
147
|
+
}
|
148
|
+
save_pkl.save(str(self.path), object=cached_predictions)
|
149
|
+
logger.debug(f"Cached predictions saved to {self.path}")
|
@@ -12,7 +12,7 @@ import numpy as np
|
|
12
12
|
import pandas as pd
|
13
13
|
from tqdm import tqdm
|
14
14
|
|
15
|
-
from autogluon.common.utils.utils import
|
15
|
+
from autogluon.common.utils.utils import seed_everything
|
16
16
|
from autogluon.core.trainer.abstract_trainer import AbstractTrainer
|
17
17
|
from autogluon.core.utils.exceptions import TimeLimitExceeded
|
18
18
|
from autogluon.core.utils.loaders import load_pkl
|
@@ -31,13 +31,12 @@ from autogluon.timeseries.utils.features import (
|
|
31
31
|
from autogluon.timeseries.utils.warning_filters import disable_tqdm, warning_filter
|
32
32
|
|
33
33
|
from .model_set_builder import TrainableModelSetBuilder, contains_searchspace
|
34
|
+
from .prediction_cache import PredictionCache, get_prediction_cache
|
34
35
|
|
35
36
|
logger = logging.getLogger("autogluon.timeseries.trainer")
|
36
37
|
|
37
38
|
|
38
39
|
class TimeSeriesTrainer(AbstractTrainer[TimeSeriesModelBase]):
|
39
|
-
_cached_predictions_filename = "cached_predictions.pkl"
|
40
|
-
|
41
40
|
max_rel_importance_score: float = 1e5
|
42
41
|
eps_abs_importance_score: float = 1e-5
|
43
42
|
max_ensemble_time_limit: float = 600.0
|
@@ -92,12 +91,10 @@ class TimeSeriesTrainer(AbstractTrainer[TimeSeriesModelBase]):
|
|
92
91
|
assert isinstance(val_splitter, AbstractWindowSplitter), "val_splitter must be of type AbstractWindowSplitter"
|
93
92
|
self.val_splitter = val_splitter
|
94
93
|
self.refit_every_n_windows = refit_every_n_windows
|
95
|
-
self.cache_predictions = cache_predictions
|
96
94
|
self.hpo_results = {}
|
97
95
|
|
98
|
-
|
99
|
-
|
100
|
-
self._cached_predictions_path.unlink()
|
96
|
+
self.prediction_cache: PredictionCache = get_prediction_cache(cache_predictions, self.path)
|
97
|
+
self.prediction_cache.clear()
|
101
98
|
|
102
99
|
@property
|
103
100
|
def path_pkl(self) -> str:
|
@@ -1055,9 +1052,10 @@ class TimeSeriesTrainer(AbstractTrainer[TimeSeriesModelBase]):
|
|
1055
1052
|
use_cache
|
1056
1053
|
If False, will ignore the cache even if it's available.
|
1057
1054
|
"""
|
1058
|
-
if
|
1059
|
-
|
1060
|
-
|
1055
|
+
if use_cache:
|
1056
|
+
model_pred_dict, pred_time_dict_marginal = self.prediction_cache.get(
|
1057
|
+
data=data, known_covariates=known_covariates
|
1058
|
+
)
|
1061
1059
|
else:
|
1062
1060
|
model_pred_dict = {}
|
1063
1061
|
pred_time_dict_marginal: dict[str, Any] = {}
|
@@ -1093,9 +1091,11 @@ class TimeSeriesTrainer(AbstractTrainer[TimeSeriesModelBase]):
|
|
1093
1091
|
|
1094
1092
|
if len(failed_models) > 0 and raise_exception_if_failed:
|
1095
1093
|
raise RuntimeError(f"Following models failed to predict: {failed_models}")
|
1096
|
-
|
1097
|
-
|
1098
|
-
|
1094
|
+
|
1095
|
+
if use_cache:
|
1096
|
+
self.prediction_cache.put(
|
1097
|
+
data=data,
|
1098
|
+
known_covariates=known_covariates,
|
1099
1099
|
model_pred_dict=model_pred_dict,
|
1100
1100
|
pred_time_dict=pred_time_dict_marginal,
|
1101
1101
|
)
|
@@ -1114,62 +1114,6 @@ class TimeSeriesTrainer(AbstractTrainer[TimeSeriesModelBase]):
|
|
1114
1114
|
pred_time_dict_total[model_name] += pred_time_dict_marginal[base_model]
|
1115
1115
|
return dict(pred_time_dict_total)
|
1116
1116
|
|
1117
|
-
@property
|
1118
|
-
def _cached_predictions_path(self) -> Path:
|
1119
|
-
return Path(self.path) / self._cached_predictions_filename
|
1120
|
-
|
1121
|
-
@staticmethod
|
1122
|
-
def _compute_dataset_hash(
|
1123
|
-
data: TimeSeriesDataFrame, known_covariates: Optional[TimeSeriesDataFrame] = None
|
1124
|
-
) -> str:
|
1125
|
-
"""Compute a unique string that identifies the time series dataset."""
|
1126
|
-
combined_hash = hash_pandas_df(data) + hash_pandas_df(known_covariates) + hash_pandas_df(data.static_features)
|
1127
|
-
return combined_hash
|
1128
|
-
|
1129
|
-
def _load_cached_predictions(self) -> dict[str, dict[str, dict[str, Any]]]:
|
1130
|
-
"""Load cached predictions from disk. If loading fails, an empty dictionary is returned."""
|
1131
|
-
if self._cached_predictions_path.exists():
|
1132
|
-
try:
|
1133
|
-
cached_predictions = load_pkl.load(str(self._cached_predictions_path))
|
1134
|
-
except Exception:
|
1135
|
-
cached_predictions = {}
|
1136
|
-
else:
|
1137
|
-
cached_predictions = {}
|
1138
|
-
return cached_predictions
|
1139
|
-
|
1140
|
-
def _get_cached_pred_dicts(
|
1141
|
-
self, dataset_hash: str
|
1142
|
-
) -> tuple[dict[str, Optional[TimeSeriesDataFrame]], dict[str, float]]:
|
1143
|
-
"""Load cached predictions for given dataset_hash from disk, if possible.
|
1144
|
-
|
1145
|
-
If loading fails for any reason, empty dicts are returned.
|
1146
|
-
"""
|
1147
|
-
cached_predictions = self._load_cached_predictions()
|
1148
|
-
if dataset_hash in cached_predictions:
|
1149
|
-
try:
|
1150
|
-
model_pred_dict = cached_predictions[dataset_hash]["model_pred_dict"]
|
1151
|
-
pred_time_dict = cached_predictions[dataset_hash]["pred_time_dict"]
|
1152
|
-
assert model_pred_dict.keys() == pred_time_dict.keys()
|
1153
|
-
return model_pred_dict, pred_time_dict
|
1154
|
-
except Exception:
|
1155
|
-
logger.warning("Cached predictions are corrupted. Predictions will be made from scratch.")
|
1156
|
-
return {}, {}
|
1157
|
-
|
1158
|
-
def _save_cached_pred_dicts(
|
1159
|
-
self,
|
1160
|
-
dataset_hash: str,
|
1161
|
-
model_pred_dict: dict[str, Optional[TimeSeriesDataFrame]],
|
1162
|
-
pred_time_dict: dict[str, float],
|
1163
|
-
) -> None:
|
1164
|
-
cached_predictions = self._load_cached_predictions()
|
1165
|
-
# Do not save results for models that failed
|
1166
|
-
cached_predictions[dataset_hash] = {
|
1167
|
-
"model_pred_dict": {k: v for k, v in model_pred_dict.items() if v is not None},
|
1168
|
-
"pred_time_dict": {k: v for k, v in pred_time_dict.items() if v is not None},
|
1169
|
-
}
|
1170
|
-
save_pkl.save(str(self._cached_predictions_path), object=cached_predictions)
|
1171
|
-
logger.debug(f"Cached predictions saved to {self._cached_predictions_path}")
|
1172
|
-
|
1173
1117
|
def _merge_refit_full_data(
|
1174
1118
|
self, train_data: TimeSeriesDataFrame, val_data: Optional[TimeSeriesDataFrame]
|
1175
1119
|
) -> TimeSeriesDataFrame:
|
@@ -364,7 +364,7 @@ class TimeSeriesFeatureGenerator:
|
|
364
364
|
def _check_required_columns_are_present(
|
365
365
|
data: TimeSeriesDataFrame, required_column_names: list[str], data_frame_name: str
|
366
366
|
) -> None:
|
367
|
-
missing_columns = pd.Index(required_column_names).difference(data.columns)
|
367
|
+
missing_columns = pd.Index(required_column_names).difference(data.columns) # type: ignore
|
368
368
|
if len(missing_columns) > 0:
|
369
369
|
raise ValueError(
|
370
370
|
f"{len(missing_columns)} columns are missing from {data_frame_name}: {reprlib.repr(missing_columns.to_list())}"
|
autogluon/timeseries/version.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: autogluon.timeseries
|
3
|
-
Version: 1.4.
|
3
|
+
Version: 1.4.1b20250903
|
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,10 +55,10 @@ 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.4.
|
59
|
-
Requires-Dist: autogluon.common==1.4.
|
60
|
-
Requires-Dist: autogluon.features==1.4.
|
61
|
-
Requires-Dist: autogluon.tabular[catboost,lightgbm,xgboost]==1.4.
|
58
|
+
Requires-Dist: autogluon.core[raytune]==1.4.1b20250903
|
59
|
+
Requires-Dist: autogluon.common==1.4.1b20250903
|
60
|
+
Requires-Dist: autogluon.features==1.4.1b20250903
|
61
|
+
Requires-Dist: autogluon.tabular[catboost,lightgbm,xgboost]==1.4.1b20250903
|
62
62
|
Provides-Extra: all
|
63
63
|
Provides-Extra: tests
|
64
64
|
Requires-Dist: pytest; extra == "tests"
|
@@ -1,18 +1,18 @@
|
|
1
|
-
autogluon.timeseries-1.4.
|
1
|
+
autogluon.timeseries-1.4.1b20250903-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=eQrqFVOmL-2JC85LgCMkbyoLpKS02Dilg1T8RUeS_LI,13887
|
5
5
|
autogluon/timeseries/predictor.py,sha256=7X4YsWYa3Xk2RI1Irf2O-c3-I82Zqhg-cgj8cj_4AoA,88427
|
6
6
|
autogluon/timeseries/regressor.py,sha256=lc8Qr3-8v4oxajtCnV3sxpUaW6vxXXJOA6Kr-qVne4k,11926
|
7
7
|
autogluon/timeseries/splitter.py,sha256=8ACkuCXeUhQGUx4jz_Vv17q814WrHJQeKvq2v4-oE6s,3158
|
8
|
-
autogluon/timeseries/version.py,sha256=
|
8
|
+
autogluon/timeseries/version.py,sha256=uHI6DT5kkDkJAqxxc3nHhMMDhvmEdq_ZnwFmY32rfjg,91
|
9
9
|
autogluon/timeseries/configs/__init__.py,sha256=wiLBwxZkDTQBJkSJ9-xz3p_yJxX0dbHe108dS1P5O6A,183
|
10
10
|
autogluon/timeseries/configs/hyperparameter_presets.py,sha256=GbI2sd3uakWtaeaMyF7B5z_lmyfb6ToK6PZEUZTyG9w,2031
|
11
11
|
autogluon/timeseries/configs/predictor_presets.py,sha256=B5HFHIelh91hhG0YYE5SJ7_14P7sylFAABgHX8n_53M,2712
|
12
12
|
autogluon/timeseries/dataset/__init__.py,sha256=UvnhAN5tjgxXTHoZMQDy64YMDj4Xxa68yY7NP4vAw0o,81
|
13
13
|
autogluon/timeseries/dataset/ts_dataframe.py,sha256=EwxKBScspwKnJTqIk2Icukk8vIrbKYObOMAkNIn4zc8,51760
|
14
14
|
autogluon/timeseries/metrics/__init__.py,sha256=YJPXxsJ0tRDXq7p-sTZSLb0DuXMJH6sT1PgbZ3tMt30,3594
|
15
|
-
autogluon/timeseries/metrics/abstract.py,sha256=
|
15
|
+
autogluon/timeseries/metrics/abstract.py,sha256=6jbluvHXfLc_cuK1Fx0ZYle2sR4WGG6YxFQhkor46Q8,11545
|
16
16
|
autogluon/timeseries/metrics/point.py,sha256=sS__n_Em7m4CUaBu3PNWQ_dHw1YCOHbEyC15fhytFL8,18308
|
17
17
|
autogluon/timeseries/metrics/quantile.py,sha256=x0cq44fXRoMiuI4BVQ7mpWk1YgrK4OwLTlJAhCHQ7Xg,4634
|
18
18
|
autogluon/timeseries/metrics/utils.py,sha256=HuDe1BNe8yJU4f_DKM913nNrUueoRaw6zhxm1-S20s0,910
|
@@ -48,15 +48,16 @@ autogluon/timeseries/models/local/naive.py,sha256=xur3WWhLaS9Iix_p_yfaStbr58nL5K
|
|
48
48
|
autogluon/timeseries/models/local/npts.py,sha256=VRZk5tEJOIentt0tLM6lxyoU8US736nHOvhSAgagYMc,4203
|
49
49
|
autogluon/timeseries/models/local/statsforecast.py,sha256=sZ6aEFzAyPNZX3rMULGWFht0Toapjb3EwHe5Rb76ZxA,33318
|
50
50
|
autogluon/timeseries/models/multi_window/__init__.py,sha256=Bq7AT2Jxdd4WNqmjTdzeqgNiwn1NCyWp4tBIWaM-zfI,60
|
51
|
-
autogluon/timeseries/models/multi_window/multi_window_model.py,sha256=
|
51
|
+
autogluon/timeseries/models/multi_window/multi_window_model.py,sha256=Hn-H2jLdeuB0_TxhAdununS8ti-iO-WSl3FOoxzcEJA,12369
|
52
52
|
autogluon/timeseries/trainer/__init__.py,sha256=_tw3iioJfvtIV7wnjtEMv0yS8oabmCFxDnGRodYE7RI,72
|
53
53
|
autogluon/timeseries/trainer/model_set_builder.py,sha256=s6tozfND3lLfst6Vxa_oP_wgCmDapyCJYFmCjkEn-es,10788
|
54
|
-
autogluon/timeseries/trainer/
|
54
|
+
autogluon/timeseries/trainer/prediction_cache.py,sha256=Vi6EbMiMheq_smA93U_MoMxYUV85RdPm0dvJFdsM8K4,5551
|
55
|
+
autogluon/timeseries/trainer/trainer.py,sha256=LF2X5UNnrU8w5h_i09SphGWvGFvZ6KvPDq89Z3GzZZQ,54959
|
55
56
|
autogluon/timeseries/transforms/__init__.py,sha256=fKlT4pkJ_8Gl7IUTc3uSDzt2Xow5iH5w6fPB3ePNrTg,127
|
56
57
|
autogluon/timeseries/transforms/covariate_scaler.py,sha256=9lEfDS4wnVZohQNnm9OcAXr3voUl83RCnctKR3O66iU,7030
|
57
58
|
autogluon/timeseries/transforms/target_scaler.py,sha256=kTQrXAsDHCnYuqfpaVuvefyTgyp_ylDpUIPz7pArjeY,6043
|
58
59
|
autogluon/timeseries/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
59
|
-
autogluon/timeseries/utils/features.py,sha256=
|
60
|
+
autogluon/timeseries/utils/features.py,sha256=tdL7jZKeySO7dgB09FweR44wPCmfWg8-ZM5uVzeyvYQ,22593
|
60
61
|
autogluon/timeseries/utils/forecast.py,sha256=yK1_eNtRUPYGs0R-VWMO4c81LrTGF57ih3yzsXVHyGY,2191
|
61
62
|
autogluon/timeseries/utils/warning_filters.py,sha256=SroNhLU3kwbD8anM58vdxWq36Z8j_uiY42mEt0ya-JI,2589
|
62
63
|
autogluon/timeseries/utils/datetime/__init__.py,sha256=bTMR8jLh1LW55vHjbOr1zvWRMF_PqbvxpS-cUcNIDWI,173
|
@@ -64,11 +65,11 @@ autogluon/timeseries/utils/datetime/base.py,sha256=3NdsH3NDq4cVAOSoy3XpaNixyNlbj
|
|
64
65
|
autogluon/timeseries/utils/datetime/lags.py,sha256=rjJtdBU0M41R1jwfmvCbo045s-6XBjhGVnGBQJ9-U1E,5997
|
65
66
|
autogluon/timeseries/utils/datetime/seasonality.py,sha256=YK_2k8hvYIMW-sJPnjGWRtCnvIOthwA2hATB3nwVoD4,834
|
66
67
|
autogluon/timeseries/utils/datetime/time_features.py,sha256=kEOFls4Nzh8nO0Pcz1DwLsC_NA3hMI4JUlZI3kuvuts,2666
|
67
|
-
autogluon.timeseries-1.4.
|
68
|
-
autogluon.timeseries-1.4.
|
69
|
-
autogluon.timeseries-1.4.
|
70
|
-
autogluon.timeseries-1.4.
|
71
|
-
autogluon.timeseries-1.4.
|
72
|
-
autogluon.timeseries-1.4.
|
73
|
-
autogluon.timeseries-1.4.
|
74
|
-
autogluon.timeseries-1.4.
|
68
|
+
autogluon.timeseries-1.4.1b20250903.dist-info/LICENSE,sha256=CeipvOyAZxBGUsFoaFqwkx54aPnIKEtm9a5u2uXxEws,10142
|
69
|
+
autogluon.timeseries-1.4.1b20250903.dist-info/METADATA,sha256=-Pfm6sMsDGYcGOZmOvJ-RhPMS_VdOEUz9PqiHGw7evc,12463
|
70
|
+
autogluon.timeseries-1.4.1b20250903.dist-info/NOTICE,sha256=7nPQuj8Kp-uXsU0S5so3-2dNU5EctS5hDXvvzzehd7E,114
|
71
|
+
autogluon.timeseries-1.4.1b20250903.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
|
72
|
+
autogluon.timeseries-1.4.1b20250903.dist-info/namespace_packages.txt,sha256=giERA4R78OkJf2ijn5slgjURlhRPzfLr7waIcGkzYAo,10
|
73
|
+
autogluon.timeseries-1.4.1b20250903.dist-info/top_level.txt,sha256=giERA4R78OkJf2ijn5slgjURlhRPzfLr7waIcGkzYAo,10
|
74
|
+
autogluon.timeseries-1.4.1b20250903.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
75
|
+
autogluon.timeseries-1.4.1b20250903.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|