autogluon.timeseries 1.2.1b20250314__py3-none-any.whl → 1.2.1b20250315__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 +4 -4
- autogluon/timeseries/models/gluonts/abstract_gluonts.py +85 -47
- autogluon/timeseries/models/gluonts/torch/models.py +1 -1
- autogluon/timeseries/version.py +1 -1
- {autogluon.timeseries-1.2.1b20250314.dist-info → autogluon.timeseries-1.2.1b20250315.dist-info}/METADATA +4 -4
- {autogluon.timeseries-1.2.1b20250314.dist-info → autogluon.timeseries-1.2.1b20250315.dist-info}/RECORD +13 -13
- /autogluon.timeseries-1.2.1b20250314-py3.9-nspkg.pth → /autogluon.timeseries-1.2.1b20250315-py3.9-nspkg.pth +0 -0
- {autogluon.timeseries-1.2.1b20250314.dist-info → autogluon.timeseries-1.2.1b20250315.dist-info}/LICENSE +0 -0
- {autogluon.timeseries-1.2.1b20250314.dist-info → autogluon.timeseries-1.2.1b20250315.dist-info}/NOTICE +0 -0
- {autogluon.timeseries-1.2.1b20250314.dist-info → autogluon.timeseries-1.2.1b20250315.dist-info}/WHEEL +0 -0
- {autogluon.timeseries-1.2.1b20250314.dist-info → autogluon.timeseries-1.2.1b20250315.dist-info}/namespace_packages.txt +0 -0
- {autogluon.timeseries-1.2.1b20250314.dist-info → autogluon.timeseries-1.2.1b20250315.dist-info}/top_level.txt +0 -0
- {autogluon.timeseries-1.2.1b20250314.dist-info → autogluon.timeseries-1.2.1b20250315.dist-info}/zip-safe +0 -0
@@ -257,7 +257,7 @@ class TimeSeriesModelBase(ModelBase, ABC):
|
|
257
257
|
return path
|
258
258
|
|
259
259
|
@classmethod
|
260
|
-
def load(cls, path: str, reset_paths: bool = True, load_oof: bool = False, verbose: bool = True) -> Self:
|
260
|
+
def load(cls, path: str, reset_paths: bool = True, load_oof: bool = False, verbose: bool = True) -> Self:
|
261
261
|
file_path = os.path.join(path, cls.model_file_name)
|
262
262
|
model = load_pkl.load(path=file_path, verbose=verbose)
|
263
263
|
if reset_paths:
|
@@ -559,7 +559,7 @@ class TimeSeriesModelBase(ModelBase, ABC):
|
|
559
559
|
|
560
560
|
|
561
561
|
class AbstractTimeSeriesModel(TimeSeriesModelBase, TimeSeriesTunable, ABC):
|
562
|
-
def fit(
|
562
|
+
def fit(
|
563
563
|
self,
|
564
564
|
train_data: TimeSeriesDataFrame,
|
565
565
|
val_data: Optional[TimeSeriesDataFrame] = None,
|
@@ -652,7 +652,7 @@ class AbstractTimeSeriesModel(TimeSeriesModelBase, TimeSeriesTunable, ABC):
|
|
652
652
|
return self
|
653
653
|
|
654
654
|
@abstractmethod
|
655
|
-
def _fit(
|
655
|
+
def _fit(
|
656
656
|
self,
|
657
657
|
train_data: TimeSeriesDataFrame,
|
658
658
|
val_data: Optional[TimeSeriesDataFrame] = None,
|
@@ -755,7 +755,7 @@ class AbstractTimeSeriesModel(TimeSeriesModelBase, TimeSeriesTunable, ABC):
|
|
755
755
|
@abstractmethod
|
756
756
|
def _predict(
|
757
757
|
self,
|
758
|
-
data:
|
758
|
+
data: TimeSeriesDataFrame,
|
759
759
|
known_covariates: Optional[TimeSeriesDataFrame] = None,
|
760
760
|
**kwargs,
|
761
761
|
) -> TimeSeriesDataFrame:
|
@@ -3,7 +3,7 @@ import os
|
|
3
3
|
import shutil
|
4
4
|
from datetime import timedelta
|
5
5
|
from pathlib import Path
|
6
|
-
from typing import Any, Callable, Dict, Iterator, List, Optional, Type, Union
|
6
|
+
from typing import TYPE_CHECKING, Any, Callable, Dict, Iterator, List, Optional, Type, Union, cast, overload
|
7
7
|
|
8
8
|
import gluonts
|
9
9
|
import gluonts.core.settings
|
@@ -12,6 +12,7 @@ import pandas as pd
|
|
12
12
|
from gluonts.core.component import from_hyperparameters
|
13
13
|
from gluonts.dataset.common import Dataset as GluonTSDataset
|
14
14
|
from gluonts.dataset.field_names import FieldName
|
15
|
+
from gluonts.env import env as gluonts_env
|
15
16
|
from gluonts.model.estimator import Estimator as GluonTSEstimator
|
16
17
|
from gluonts.model.forecast import Forecast, QuantileForecast, SampleForecast
|
17
18
|
from gluonts.model.predictor import Predictor as GluonTSPredictor
|
@@ -26,6 +27,9 @@ from autogluon.timeseries.models.abstract import AbstractTimeSeriesModel
|
|
26
27
|
from autogluon.timeseries.utils.datetime import norm_freq_str
|
27
28
|
from autogluon.timeseries.utils.warning_filters import disable_root_logger, warning_filter
|
28
29
|
|
30
|
+
if TYPE_CHECKING:
|
31
|
+
from gluonts.torch.model.forecast import DistributionForecast
|
32
|
+
|
29
33
|
# NOTE: We avoid imports for torch and lightning.pytorch at the top level and hide them inside class methods.
|
30
34
|
# This is done to skip these imports during multiprocessing (which may cause bugs)
|
31
35
|
|
@@ -48,7 +52,7 @@ class SimpleGluonTSDataset(GluonTSDataset):
|
|
48
52
|
past_feat_dynamic_cat: Optional[np.ndarray] = None,
|
49
53
|
past_feat_dynamic_real: Optional[np.ndarray] = None,
|
50
54
|
includes_future: bool = False,
|
51
|
-
prediction_length: int = None,
|
55
|
+
prediction_length: Optional[int] = None,
|
52
56
|
):
|
53
57
|
assert target_df is not None
|
54
58
|
# Convert TimeSeriesDataFrame to pd.Series for faster processing
|
@@ -75,7 +79,7 @@ class SimpleGluonTSDataset(GluonTSDataset):
|
|
75
79
|
assert len(self.item_ids) == len(self.start_timestamps)
|
76
80
|
|
77
81
|
@staticmethod
|
78
|
-
def _astype(array: Optional[np.ndarray], dtype: np.
|
82
|
+
def _astype(array: Optional[np.ndarray], dtype: Type[np.generic]) -> Optional[np.ndarray]:
|
79
83
|
if array is None:
|
80
84
|
return None
|
81
85
|
else:
|
@@ -88,6 +92,7 @@ class SimpleGluonTSDataset(GluonTSDataset):
|
|
88
92
|
For example, ME freq must be converted to M when creating a pd.Period.
|
89
93
|
"""
|
90
94
|
offset = pd.tseries.frequencies.to_offset(freq)
|
95
|
+
assert offset is not None
|
91
96
|
freq_name = norm_freq_str(offset)
|
92
97
|
if freq_name == "SME":
|
93
98
|
# Replace unsupported frequency "SME" with "2W"
|
@@ -123,6 +128,9 @@ class SimpleGluonTSDataset(GluonTSDataset):
|
|
123
128
|
|
124
129
|
# Dynamic features that may extend into the future
|
125
130
|
if self.includes_future:
|
131
|
+
assert self.prediction_length is not None, (
|
132
|
+
"Prediction length must be provided if includes_future is True"
|
133
|
+
)
|
126
134
|
start_idx = start_idx + j * self.prediction_length
|
127
135
|
end_idx = end_idx + (j + 1) * self.prediction_length
|
128
136
|
if self.feat_dynamic_cat is not None:
|
@@ -171,8 +179,8 @@ class AbstractGluonTSModel(AbstractTimeSeriesModel):
|
|
171
179
|
prediction_length: int = 1,
|
172
180
|
path: Optional[str] = None,
|
173
181
|
name: Optional[str] = None,
|
174
|
-
eval_metric: str = None,
|
175
|
-
hyperparameters: Dict[str, Any] = None,
|
182
|
+
eval_metric: Optional[str] = None,
|
183
|
+
hyperparameters: Optional[Dict[str, Any]] = None,
|
176
184
|
**kwargs, # noqa
|
177
185
|
):
|
178
186
|
super().__init__(
|
@@ -200,25 +208,27 @@ class AbstractGluonTSModel(AbstractTimeSeriesModel):
|
|
200
208
|
self.past_feat_dynamic_cat_cardinality: List[int] = []
|
201
209
|
self.negative_data = True
|
202
210
|
|
203
|
-
def save(self, path: str = None, verbose: bool = True) -> str:
|
211
|
+
def save(self, path: Optional[str] = None, verbose: bool = True) -> str:
|
204
212
|
# we flush callbacks instance variable if it has been set. it can keep weak references which breaks training
|
205
213
|
self.callbacks = []
|
206
214
|
# The GluonTS predictor is serialized using custom logic
|
207
215
|
predictor = self.gts_predictor
|
208
216
|
self.gts_predictor = None
|
209
|
-
|
217
|
+
saved_path = Path(super().save(path=path, verbose=verbose))
|
210
218
|
|
211
219
|
with disable_root_logger():
|
212
220
|
if predictor:
|
213
|
-
Path.mkdir(
|
214
|
-
predictor.serialize(
|
221
|
+
Path.mkdir(saved_path / self.gluonts_model_path, exist_ok=True)
|
222
|
+
predictor.serialize(saved_path / self.gluonts_model_path)
|
215
223
|
|
216
224
|
self.gts_predictor = predictor
|
217
225
|
|
218
|
-
return str(
|
226
|
+
return str(saved_path)
|
219
227
|
|
220
228
|
@classmethod
|
221
|
-
def load(
|
229
|
+
def load(
|
230
|
+
cls, path: str, reset_paths: bool = True, load_oof: bool = False, verbose: bool = True
|
231
|
+
) -> "AbstractGluonTSModel":
|
222
232
|
from gluonts.torch.model.predictor import PyTorchPredictor
|
223
233
|
|
224
234
|
with warning_filter():
|
@@ -243,6 +253,9 @@ class AbstractGluonTSModel(AbstractTimeSeriesModel):
|
|
243
253
|
self.num_feat_static_cat = len(self.metadata.static_features_cat)
|
244
254
|
self.num_feat_static_real = len(self.metadata.static_features_real)
|
245
255
|
if self.num_feat_static_cat > 0:
|
256
|
+
assert dataset.static_features is not None, (
|
257
|
+
"Static features must be provided if num_feat_static_cat > 0"
|
258
|
+
)
|
246
259
|
feat_static_cat = dataset.static_features[self.metadata.static_features_cat]
|
247
260
|
self.feat_static_cat_cardinality = feat_static_cat.nunique().tolist()
|
248
261
|
|
@@ -259,7 +272,7 @@ class AbstractGluonTSModel(AbstractTimeSeriesModel):
|
|
259
272
|
self._ohe_generator_known = OneHotEncoder(
|
260
273
|
max_levels=model_params.get("max_cat_cardinality", 100),
|
261
274
|
sparse=False,
|
262
|
-
dtype="float32",
|
275
|
+
dtype="float32", # type: ignore
|
263
276
|
)
|
264
277
|
feat_dynamic_cat_ohe = self._ohe_generator_known.fit_transform(pd.DataFrame(feat_dynamic_cat))
|
265
278
|
self.num_feat_dynamic_cat = 0
|
@@ -278,7 +291,7 @@ class AbstractGluonTSModel(AbstractTimeSeriesModel):
|
|
278
291
|
self._ohe_generator_past = OneHotEncoder(
|
279
292
|
max_levels=model_params.get("max_cat_cardinality", 100),
|
280
293
|
sparse=False,
|
281
|
-
dtype="float32",
|
294
|
+
dtype="float32", # type: ignore
|
282
295
|
)
|
283
296
|
past_feat_dynamic_cat_ohe = self._ohe_generator_past.fit_transform(
|
284
297
|
pd.DataFrame(past_feat_dynamic_cat)
|
@@ -368,23 +381,33 @@ class AbstractGluonTSModel(AbstractTimeSeriesModel):
|
|
368
381
|
return torch.cuda.is_available()
|
369
382
|
|
370
383
|
def get_minimum_resources(self, is_gpu_available: bool = False) -> Dict[str, Union[int, float]]:
|
371
|
-
minimum_resources = {"num_cpus": 1}
|
384
|
+
minimum_resources: Dict[str, Union[int, float]] = {"num_cpus": 1}
|
372
385
|
# if GPU is available, we train with 1 GPU per trial
|
373
386
|
if is_gpu_available:
|
374
387
|
minimum_resources["num_gpus"] = 1
|
375
388
|
return minimum_resources
|
376
389
|
|
390
|
+
@overload
|
391
|
+
def _to_gluonts_dataset(self, time_series_df: None, known_covariates=None) -> None: ...
|
392
|
+
@overload
|
393
|
+
def _to_gluonts_dataset(self, time_series_df: TimeSeriesDataFrame, known_covariates=None) -> GluonTSDataset: ...
|
377
394
|
def _to_gluonts_dataset(
|
378
395
|
self, time_series_df: Optional[TimeSeriesDataFrame], known_covariates: Optional[TimeSeriesDataFrame] = None
|
379
396
|
) -> Optional[GluonTSDataset]:
|
380
397
|
if time_series_df is not None:
|
381
398
|
# TODO: Preprocess real-valued features with StdScaler?
|
382
399
|
if self.num_feat_static_cat > 0:
|
400
|
+
assert time_series_df.static_features is not None, (
|
401
|
+
"Static features must be provided if num_feat_static_cat > 0"
|
402
|
+
)
|
383
403
|
feat_static_cat = time_series_df.static_features[self.metadata.static_features_cat].to_numpy()
|
384
404
|
else:
|
385
405
|
feat_static_cat = None
|
386
406
|
|
387
407
|
if self.num_feat_static_real > 0:
|
408
|
+
assert time_series_df.static_features is not None, (
|
409
|
+
"Static features must be provided if num_feat_static_real > 0"
|
410
|
+
)
|
388
411
|
feat_static_real = time_series_df.static_features[self.metadata.static_features_real].to_numpy()
|
389
412
|
else:
|
390
413
|
feat_static_real = None
|
@@ -393,7 +416,7 @@ class AbstractGluonTSModel(AbstractTimeSeriesModel):
|
|
393
416
|
# Convert TSDF -> DF to avoid overhead / input validation
|
394
417
|
df = pd.DataFrame(time_series_df)
|
395
418
|
if known_covariates is not None:
|
396
|
-
known_covariates = pd.DataFrame(known_covariates)
|
419
|
+
known_covariates = pd.DataFrame(known_covariates) # type: ignore
|
397
420
|
if self.num_feat_dynamic_cat > 0:
|
398
421
|
feat_dynamic_cat = df[self.metadata.known_covariates_cat].to_numpy()
|
399
422
|
if known_covariates is not None:
|
@@ -414,9 +437,11 @@ class AbstractGluonTSModel(AbstractTimeSeriesModel):
|
|
414
437
|
assert len(feat_dynamic_real) == expected_known_covariates_len
|
415
438
|
# Categorical covariates are one-hot-encoded as real
|
416
439
|
if self._ohe_generator_known is not None:
|
417
|
-
feat_dynamic_cat_ohe = self._ohe_generator_known.transform(
|
440
|
+
feat_dynamic_cat_ohe: np.ndarray = self._ohe_generator_known.transform(
|
441
|
+
df[self.metadata.known_covariates_cat]
|
442
|
+
) # type: ignore
|
418
443
|
if known_covariates is not None:
|
419
|
-
future_dynamic_cat_ohe = self._ohe_generator_known.transform(
|
444
|
+
future_dynamic_cat_ohe: np.ndarray = self._ohe_generator_known.transform( # type: ignore
|
420
445
|
known_covariates[self.metadata.known_covariates_cat]
|
421
446
|
)
|
422
447
|
feat_dynamic_cat_ohe = np.concatenate([feat_dynamic_cat_ohe, future_dynamic_cat_ohe])
|
@@ -433,7 +458,7 @@ class AbstractGluonTSModel(AbstractTimeSeriesModel):
|
|
433
458
|
if self.num_past_feat_dynamic_real > 0:
|
434
459
|
past_feat_dynamic_real = df[self.metadata.past_covariates_real].to_numpy()
|
435
460
|
if self._ohe_generator_past is not None:
|
436
|
-
past_feat_dynamic_cat_ohe = self._ohe_generator_past.transform(
|
461
|
+
past_feat_dynamic_cat_ohe: np.ndarray = self._ohe_generator_past.transform( # type: ignore
|
437
462
|
df[self.metadata.past_covariates_cat]
|
438
463
|
)
|
439
464
|
past_feat_dynamic_real = np.concatenate(
|
@@ -442,8 +467,9 @@ class AbstractGluonTSModel(AbstractTimeSeriesModel):
|
|
442
467
|
else:
|
443
468
|
past_feat_dynamic_real = None
|
444
469
|
|
470
|
+
assert self.freq is not None
|
445
471
|
return SimpleGluonTSDataset(
|
446
|
-
target_df=time_series_df[[self.target]],
|
472
|
+
target_df=time_series_df[[self.target]], # type: ignore
|
447
473
|
freq=self.freq,
|
448
474
|
target_column=self.target,
|
449
475
|
feat_static_cat=feat_static_cat,
|
@@ -462,13 +488,15 @@ class AbstractGluonTSModel(AbstractTimeSeriesModel):
|
|
462
488
|
self,
|
463
489
|
train_data: TimeSeriesDataFrame,
|
464
490
|
val_data: Optional[TimeSeriesDataFrame] = None,
|
465
|
-
time_limit:
|
491
|
+
time_limit: Optional[float] = None,
|
492
|
+
num_cpus: Optional[int] = None,
|
493
|
+
num_gpus: Optional[int] = None,
|
494
|
+
verbosity: int = 2,
|
466
495
|
**kwargs,
|
467
496
|
) -> None:
|
468
497
|
# necessary to initialize the loggers
|
469
498
|
import lightning.pytorch # noqa
|
470
499
|
|
471
|
-
verbosity = kwargs.get("verbosity", 2)
|
472
500
|
for logger_name in logging.root.manager.loggerDict:
|
473
501
|
if "lightning" in logger_name:
|
474
502
|
pl_logger = logging.getLogger(logger_name)
|
@@ -492,15 +520,15 @@ class AbstractGluonTSModel(AbstractTimeSeriesModel):
|
|
492
520
|
self._deferred_init_params_aux(train_data)
|
493
521
|
|
494
522
|
estimator = self._get_estimator()
|
495
|
-
with warning_filter(), disable_root_logger(), gluonts.core.settings.let(
|
523
|
+
with warning_filter(), disable_root_logger(), gluonts.core.settings.let(gluonts_env, use_tqdm=False):
|
496
524
|
self.gts_predictor = estimator.train(
|
497
525
|
self._to_gluonts_dataset(train_data),
|
498
526
|
validation_data=self._to_gluonts_dataset(val_data),
|
499
|
-
cache_data=True,
|
527
|
+
cache_data=True, # type: ignore
|
500
528
|
)
|
501
529
|
# Increase batch size during prediction to speed up inference
|
502
530
|
if init_args["predict_batch_size"] is not None:
|
503
|
-
self.gts_predictor.batch_size = init_args["predict_batch_size"]
|
531
|
+
self.gts_predictor.batch_size = init_args["predict_batch_size"] # type: ignore
|
504
532
|
|
505
533
|
lightning_logs_dir = Path(self.path) / "lightning_logs"
|
506
534
|
if not keep_lightning_logs and lightning_logs_dir.exists() and lightning_logs_dir.is_dir():
|
@@ -509,7 +537,7 @@ class AbstractGluonTSModel(AbstractTimeSeriesModel):
|
|
509
537
|
|
510
538
|
def _get_callbacks(
|
511
539
|
self,
|
512
|
-
time_limit:
|
540
|
+
time_limit: Optional[float],
|
513
541
|
early_stopping_patience: Optional[int] = None,
|
514
542
|
) -> List[Callable]:
|
515
543
|
"""Retrieve a list of callback objects for the GluonTS trainer"""
|
@@ -531,8 +559,8 @@ class AbstractGluonTSModel(AbstractTimeSeriesModel):
|
|
531
559
|
if self.gts_predictor is None:
|
532
560
|
raise ValueError("Please fit the model before predicting.")
|
533
561
|
|
534
|
-
with warning_filter(), gluonts.core.settings.let(
|
535
|
-
predicted_targets = self._predict_gluonts_forecasts(data, known_covariates=known_covariates
|
562
|
+
with warning_filter(), gluonts.core.settings.let(gluonts_env, use_tqdm=False):
|
563
|
+
predicted_targets = self._predict_gluonts_forecasts(data, known_covariates=known_covariates)
|
536
564
|
df = self._gluonts_forecasts_to_data_frame(
|
537
565
|
predicted_targets,
|
538
566
|
forecast_index=self.get_forecast_horizon_index(data),
|
@@ -540,14 +568,19 @@ class AbstractGluonTSModel(AbstractTimeSeriesModel):
|
|
540
568
|
return df
|
541
569
|
|
542
570
|
def _predict_gluonts_forecasts(
|
543
|
-
self,
|
571
|
+
self,
|
572
|
+
data: TimeSeriesDataFrame,
|
573
|
+
known_covariates: Optional[TimeSeriesDataFrame] = None,
|
574
|
+
num_samples: Optional[int] = None,
|
544
575
|
) -> List[Forecast]:
|
576
|
+
assert self.gts_predictor is not None, "GluonTS models must be fit before predicting."
|
545
577
|
gts_data = self._to_gluonts_dataset(data, known_covariates=known_covariates)
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
578
|
+
return list(
|
579
|
+
self.gts_predictor.predict(
|
580
|
+
dataset=gts_data,
|
581
|
+
num_samples=num_samples or self.default_num_samples,
|
582
|
+
)
|
583
|
+
)
|
551
584
|
|
552
585
|
def _stack_quantile_forecasts(self, forecasts: List[QuantileForecast], item_ids: pd.Index) -> pd.DataFrame:
|
553
586
|
# GluonTS always saves item_id as a string
|
@@ -574,17 +607,25 @@ class AbstractGluonTSModel(AbstractTimeSeriesModel):
|
|
574
607
|
forecast_array = np.concatenate([mean, quantiles], axis=1)
|
575
608
|
return pd.DataFrame(forecast_array, columns=["mean"] + [str(q) for q in self.quantile_levels])
|
576
609
|
|
577
|
-
def _stack_distribution_forecasts(
|
610
|
+
def _stack_distribution_forecasts(
|
611
|
+
self, forecasts: List["DistributionForecast"], item_ids: pd.Index
|
612
|
+
) -> pd.DataFrame:
|
578
613
|
import torch
|
579
614
|
from gluonts.torch.distributions import AffineTransformed
|
580
615
|
from torch.distributions import Distribution
|
581
616
|
|
582
617
|
# Sort forecasts in the same order as in the dataset
|
583
618
|
item_id_to_forecast = {str(f.item_id): f for f in forecasts}
|
584
|
-
|
619
|
+
dist_forecasts = [item_id_to_forecast[str(item_id)] for item_id in item_ids]
|
620
|
+
|
621
|
+
assert all(isinstance(f.distribution, AffineTransformed) for f in dist_forecasts), (
|
622
|
+
"Expected forecast.distribution to be an instance of AffineTransformed"
|
623
|
+
)
|
585
624
|
|
586
625
|
def stack_distributions(distributions: List[Distribution]) -> Distribution:
|
587
626
|
"""Stack multiple torch.Distribution objects into a single distribution"""
|
627
|
+
last_dist: Distribution = distributions[-1]
|
628
|
+
|
588
629
|
params_per_dist = []
|
589
630
|
for dist in distributions:
|
590
631
|
params = {name: getattr(dist, name) for name in dist.arg_constraints.keys()}
|
@@ -593,22 +634,19 @@ class AbstractGluonTSModel(AbstractTimeSeriesModel):
|
|
593
634
|
assert len(set(tuple(p.keys()) for p in params_per_dist)) == 1
|
594
635
|
|
595
636
|
stacked_params = {}
|
596
|
-
for key in
|
637
|
+
for key in last_dist.arg_constraints.keys():
|
597
638
|
stacked_params[key] = torch.cat([p[key] for p in params_per_dist])
|
598
|
-
return
|
599
|
-
|
600
|
-
if not isinstance(forecasts[0].distribution, AffineTransformed):
|
601
|
-
raise AssertionError("Expected forecast.distribution to be an instance of AffineTransformed")
|
639
|
+
return last_dist.__class__(**stacked_params)
|
602
640
|
|
603
641
|
# We stack all forecast distribution into a single Distribution object.
|
604
642
|
# This dramatically speeds up the quantiles calculation.
|
605
|
-
stacked_base_dist = stack_distributions([f.distribution.base_dist for f in
|
643
|
+
stacked_base_dist = stack_distributions([f.distribution.base_dist for f in dist_forecasts]) # type: ignore
|
606
644
|
|
607
|
-
stacked_loc = torch.cat([f.distribution.loc for f in
|
645
|
+
stacked_loc = torch.cat([f.distribution.loc for f in dist_forecasts]) # type: ignore
|
608
646
|
if stacked_loc.shape != stacked_base_dist.batch_shape:
|
609
647
|
stacked_loc = stacked_loc.repeat_interleave(self.prediction_length)
|
610
648
|
|
611
|
-
stacked_scale = torch.cat([f.distribution.scale for f in
|
649
|
+
stacked_scale = torch.cat([f.distribution.scale for f in dist_forecasts]) # type: ignore
|
612
650
|
if stacked_scale.shape != stacked_base_dist.batch_shape:
|
613
651
|
stacked_scale = stacked_scale.repeat_interleave(self.prediction_length)
|
614
652
|
|
@@ -616,7 +654,7 @@ class AbstractGluonTSModel(AbstractTimeSeriesModel):
|
|
616
654
|
|
617
655
|
mean_prediction = stacked_dist.mean.cpu().detach().numpy()
|
618
656
|
quantiles = torch.tensor(self.quantile_levels, device=stacked_dist.mean.device).reshape(-1, 1)
|
619
|
-
quantile_predictions = stacked_dist.icdf(quantiles).cpu().detach().numpy()
|
657
|
+
quantile_predictions = stacked_dist.icdf(quantiles).cpu().detach().numpy() # type: ignore
|
620
658
|
forecast_array = np.vstack([mean_prediction, quantile_predictions]).T
|
621
659
|
return pd.DataFrame(forecast_array, columns=["mean"] + [str(q) for q in self.quantile_levels])
|
622
660
|
|
@@ -629,11 +667,11 @@ class AbstractGluonTSModel(AbstractTimeSeriesModel):
|
|
629
667
|
|
630
668
|
item_ids = forecast_index.unique(level=ITEMID)
|
631
669
|
if isinstance(forecasts[0], SampleForecast):
|
632
|
-
forecast_df = self._stack_sample_forecasts(forecasts, item_ids)
|
670
|
+
forecast_df = self._stack_sample_forecasts(cast(List[SampleForecast], forecasts), item_ids)
|
633
671
|
elif isinstance(forecasts[0], QuantileForecast):
|
634
|
-
forecast_df = self._stack_quantile_forecasts(forecasts, item_ids)
|
672
|
+
forecast_df = self._stack_quantile_forecasts(cast(List[QuantileForecast], forecasts), item_ids)
|
635
673
|
elif isinstance(forecasts[0], DistributionForecast):
|
636
|
-
forecast_df = self._stack_distribution_forecasts(forecasts, item_ids)
|
674
|
+
forecast_df = self._stack_distribution_forecasts(cast(List[DistributionForecast], forecasts), item_ids)
|
637
675
|
else:
|
638
676
|
raise ValueError(f"Unrecognized forecast type {type(forecasts[0])}")
|
639
677
|
|
@@ -94,7 +94,7 @@ class DeepARModel(AbstractGluonTSModel):
|
|
94
94
|
init_kwargs["num_feat_static_real"] = self.num_feat_static_real
|
95
95
|
init_kwargs["cardinality"] = self.feat_static_cat_cardinality
|
96
96
|
init_kwargs["num_feat_dynamic_real"] = self.num_feat_dynamic_real
|
97
|
-
init_kwargs.setdefault("lags_seq", get_lags_for_frequency(self.freq))
|
97
|
+
init_kwargs.setdefault("lags_seq", get_lags_for_frequency(self.freq)) # type: ignore
|
98
98
|
init_kwargs.setdefault("time_features", get_time_features_for_frequency(self.freq))
|
99
99
|
return init_kwargs
|
100
100
|
|
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.1b20250315
|
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.1b20250315
|
59
|
+
Requires-Dist: autogluon.common==1.2.1b20250315
|
60
|
+
Requires-Dist: autogluon.tabular[catboost,lightgbm,xgboost]==1.2.1b20250315
|
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,4 +1,4 @@
|
|
1
|
-
autogluon.timeseries-1.2.
|
1
|
+
autogluon.timeseries-1.2.1b20250315-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
|
@@ -6,7 +6,7 @@ autogluon/timeseries/predictor.py,sha256=DgKNvDfduVyauR7MXQZk04JyT3fc5erXAGVp3XO
|
|
6
6
|
autogluon/timeseries/regressor.py,sha256=3MlTpP-M1ayTZ52UQDK0wIMMFUijPep-iEyftlDdKPg,11804
|
7
7
|
autogluon/timeseries/splitter.py,sha256=yzPca9p2bWV-_VJAptUyyzQsxu-uixAdpMoGQtDzMD4,3205
|
8
8
|
autogluon/timeseries/trainer.py,sha256=L9FT5qERcqlWTgH9IgE6QsO0aBNj2nivRKF2Oy4UJOk,57250
|
9
|
-
autogluon/timeseries/version.py,sha256=
|
9
|
+
autogluon/timeseries/version.py,sha256=PqgFWNvO1pvwKw3vhYXewfczouwj7sbU4yElZ25sDeE,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=qfpxoT3G3FEM2_P41nBfTXGNuLZTneCXAVa15guW5do,12292
|
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=6Q9m3rQi2H1nMRbcn-Jl2D3MowwQUThjCaXgrwtF-IM,34749
|
23
23
|
autogluon/timeseries/models/abstract/model_trial.py,sha256=ENPg_7nsdxIvaNM0o0UShZ3x8jFlRmwRc5m0fGPC0TM,3720
|
24
24
|
autogluon/timeseries/models/abstract/tunable.py,sha256=SFl4vjkb6BfFFaRPVdftnnLYlIyCThutLHxiiAlV6tY,7168
|
25
25
|
autogluon/timeseries/models/autogluon_tabular/__init__.py,sha256=r9i6jWcyeLHYClkcMSKRVsfrkBUMxpDrTATNTBc_qgQ,136
|
@@ -37,9 +37,9 @@ autogluon/timeseries/models/ensemble/__init__.py,sha256=kFr11Gmt7lQJu9Rr8HuIPphQ
|
|
37
37
|
autogluon/timeseries/models/ensemble/abstract_timeseries_ensemble.py,sha256=LzL64JASiwkLsuFxGToXJGRItcMxq5_Ig2QP5Zm7SHw,3537
|
38
38
|
autogluon/timeseries/models/ensemble/greedy_ensemble.py,sha256=v5A2xv4d_QynA1GWD7iqmn-VVEFpD88Oiswyp72yBCc,7321
|
39
39
|
autogluon/timeseries/models/gluonts/__init__.py,sha256=asC1PTj4j9xMbilvk1IT1julnpeoKbv5ZNuAR6-DFgA,361
|
40
|
-
autogluon/timeseries/models/gluonts/abstract_gluonts.py,sha256=
|
40
|
+
autogluon/timeseries/models/gluonts/abstract_gluonts.py,sha256=WmLuPCmUqc_bxrH03Hf6cVreBilPHeUWZ6209PGNQnA,32587
|
41
41
|
autogluon/timeseries/models/gluonts/torch/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
42
|
-
autogluon/timeseries/models/gluonts/torch/models.py,sha256=
|
42
|
+
autogluon/timeseries/models/gluonts/torch/models.py,sha256=33glIsbgxrCfn4HUkaK4uX4QlVp1CmwU-6rYVKfM4AM,25688
|
43
43
|
autogluon/timeseries/models/local/__init__.py,sha256=e2UImoJhmj70E148IIObv90C_bHxgyLNk6YsS4p7pfs,701
|
44
44
|
autogluon/timeseries/models/local/abstract_local_model.py,sha256=CYDvOXs7ZNzyz75gMOAKI1socB_qGep51FSPfzXMopA,11948
|
45
45
|
autogluon/timeseries/models/local/naive.py,sha256=iwRcFMFmJKPWPbD9TWaIUS51oav69F_VAp6-jb_5SUE,7249
|
@@ -59,11 +59,11 @@ autogluon/timeseries/utils/datetime/base.py,sha256=3NdsH3NDq4cVAOSoy3XpaNixyNlbj
|
|
59
59
|
autogluon/timeseries/utils/datetime/lags.py,sha256=gQDk5_zmsY5DUWDUpSaCKYkQ9nHKKY-LsywJQRAoYSk,5988
|
60
60
|
autogluon/timeseries/utils/datetime/seasonality.py,sha256=YK_2k8hvYIMW-sJPnjGWRtCnvIOthwA2hATB3nwVoD4,834
|
61
61
|
autogluon/timeseries/utils/datetime/time_features.py,sha256=MjLi3zQ00uWWJtXH9oGX2GJkTbvjdSiuabSa4kcVuxE,2672
|
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.
|
69
|
-
autogluon.timeseries-1.2.
|
62
|
+
autogluon.timeseries-1.2.1b20250315.dist-info/LICENSE,sha256=CeipvOyAZxBGUsFoaFqwkx54aPnIKEtm9a5u2uXxEws,10142
|
63
|
+
autogluon.timeseries-1.2.1b20250315.dist-info/METADATA,sha256=IQ0LaAvGm29hMI8NrcxdS56S3Pq68hgJi79ElHvpeZM,12684
|
64
|
+
autogluon.timeseries-1.2.1b20250315.dist-info/NOTICE,sha256=7nPQuj8Kp-uXsU0S5so3-2dNU5EctS5hDXvvzzehd7E,114
|
65
|
+
autogluon.timeseries-1.2.1b20250315.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
|
66
|
+
autogluon.timeseries-1.2.1b20250315.dist-info/namespace_packages.txt,sha256=giERA4R78OkJf2ijn5slgjURlhRPzfLr7waIcGkzYAo,10
|
67
|
+
autogluon.timeseries-1.2.1b20250315.dist-info/top_level.txt,sha256=giERA4R78OkJf2ijn5slgjURlhRPzfLr7waIcGkzYAo,10
|
68
|
+
autogluon.timeseries-1.2.1b20250315.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
69
|
+
autogluon.timeseries-1.2.1b20250315.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|