autogluon.timeseries 1.2.1b20250114__tar.gz → 1.2.1b20250116__tar.gz

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.
Files changed (71) hide show
  1. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/PKG-INFO +1 -1
  2. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/setup.py +4 -4
  3. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/dataset/ts_dataframe.py +7 -6
  4. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/metrics/__init__.py +8 -8
  5. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/metrics/abstract.py +1 -1
  6. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/metrics/point.py +6 -3
  7. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/models/abstract/abstract_timeseries_model.py +10 -5
  8. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/models/ensemble/abstract_timeseries_ensemble.py +2 -2
  9. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/models/ensemble/greedy_ensemble.py +1 -1
  10. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/models/presets.py +2 -2
  11. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/predictor.py +1 -1
  12. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/splitter.py +3 -0
  13. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/trainer/abstract_trainer.py +53 -40
  14. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/trainer/auto_trainer.py +1 -0
  15. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/version.py +2 -1
  16. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon.timeseries.egg-info/PKG-INFO +1 -1
  17. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon.timeseries.egg-info/requires.txt +7 -7
  18. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/setup.cfg +0 -0
  19. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/__init__.py +0 -0
  20. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/configs/__init__.py +0 -0
  21. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/configs/presets_configs.py +0 -0
  22. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/dataset/__init__.py +0 -0
  23. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/evaluator.py +0 -0
  24. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/learner.py +0 -0
  25. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/metrics/quantile.py +0 -0
  26. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/metrics/utils.py +0 -0
  27. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/models/__init__.py +0 -0
  28. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/models/abstract/__init__.py +0 -0
  29. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/models/abstract/model_trial.py +0 -0
  30. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/models/autogluon_tabular/__init__.py +0 -0
  31. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/models/autogluon_tabular/mlforecast.py +0 -0
  32. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/models/autogluon_tabular/transforms.py +0 -0
  33. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/models/autogluon_tabular/utils.py +0 -0
  34. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/models/chronos/__init__.py +0 -0
  35. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/models/chronos/model.py +0 -0
  36. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/models/chronos/pipeline/__init__.py +0 -0
  37. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/models/chronos/pipeline/base.py +0 -0
  38. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/models/chronos/pipeline/chronos.py +0 -0
  39. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/models/chronos/pipeline/chronos_bolt.py +0 -0
  40. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/models/chronos/pipeline/utils.py +0 -0
  41. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/models/ensemble/__init__.py +0 -0
  42. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/models/gluonts/__init__.py +0 -0
  43. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/models/gluonts/abstract_gluonts.py +0 -0
  44. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/models/gluonts/torch/__init__.py +0 -0
  45. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/models/gluonts/torch/models.py +0 -0
  46. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/models/local/__init__.py +0 -0
  47. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/models/local/abstract_local_model.py +0 -0
  48. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/models/local/naive.py +0 -0
  49. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/models/local/npts.py +0 -0
  50. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/models/local/statsforecast.py +0 -0
  51. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/models/multi_window/__init__.py +0 -0
  52. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/models/multi_window/multi_window_model.py +0 -0
  53. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/regressor.py +0 -0
  54. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/trainer/__init__.py +0 -0
  55. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/transforms/__init__.py +0 -0
  56. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/transforms/covariate_scaler.py +0 -0
  57. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/transforms/target_scaler.py +0 -0
  58. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/utils/__init__.py +0 -0
  59. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/utils/datetime/__init__.py +0 -0
  60. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/utils/datetime/base.py +0 -0
  61. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/utils/datetime/lags.py +0 -0
  62. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/utils/datetime/seasonality.py +0 -0
  63. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/utils/datetime/time_features.py +0 -0
  64. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/utils/features.py +0 -0
  65. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/utils/forecast.py +0 -0
  66. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon/timeseries/utils/warning_filters.py +0 -0
  67. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon.timeseries.egg-info/SOURCES.txt +0 -0
  68. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon.timeseries.egg-info/dependency_links.txt +0 -0
  69. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon.timeseries.egg-info/namespace_packages.txt +0 -0
  70. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon.timeseries.egg-info/top_level.txt +0 -0
  71. {autogluon.timeseries-1.2.1b20250114 → autogluon.timeseries-1.2.1b20250116}/src/autogluon.timeseries.egg-info/zip-safe +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: autogluon.timeseries
3
- Version: 1.2.1b20250114
3
+ Version: 1.2.1b20250116
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
@@ -32,10 +32,10 @@ install_requires = [
32
32
  "accelerate", # version range defined in `core/_setup_utils.py`
33
33
  "gluonts>=0.15.0,<0.17",
34
34
  "networkx", # version range defined in `core/_setup_utils.py`
35
- "statsforecast>=1.7.0,<1.8",
36
- "mlforecast==0.13.4",
37
- "utilsforecast>=0.2.3,<0.2.5", # to prevent breaking changes that propagate through mlforecast's dependency
38
- "coreforecast==0.0.12", # to prevent breaking changes that propagate through mlforecast's dependency
35
+ "statsforecast>=1.7.0,<2.0.1",
36
+ "mlforecast>0.13,<0.14",
37
+ "utilsforecast>=0.2.3,<0.2.11", # to prevent breaking changes that propagate through mlforecast's dependency
38
+ "coreforecast>=0.0.12,<0.0.16", # to prevent breaking changes that propagate through mlforecast's dependency
39
39
  "fugue>=0.9.0", # prevent dependency clash with omegaconf
40
40
  "tqdm", # version range defined in `core/_setup_utils.py`
41
41
  "orjson~=3.9", # use faster JSON implementation in GluonTS
@@ -12,7 +12,7 @@ from typing import Any, List, Optional, Tuple, Type, Union
12
12
 
13
13
  import pandas as pd
14
14
  from joblib.parallel import Parallel, delayed
15
- from pandas.core.internals import ArrayManager, BlockManager
15
+ from pandas.core.internals import ArrayManager, BlockManager # type: ignore
16
16
 
17
17
  from autogluon.common.loaders import load_pd
18
18
 
@@ -174,7 +174,7 @@ class TimeSeriesDataFrame(pd.DataFrame, TimeSeriesDataFrameDeprecatedMixin):
174
174
  data = self._construct_tsdf_from_iterable_dataset(data, num_cpus=num_cpus)
175
175
  else:
176
176
  raise ValueError(f"data must be a pd.DataFrame, Iterable, string or Path (received {type(data)}).")
177
- super().__init__(data=data, *args, **kwargs)
177
+ super().__init__(data=data, *args, **kwargs) # type: ignore
178
178
  self._static_features: Optional[pd.DataFrame] = None
179
179
  if static_features is not None:
180
180
  self.static_features = self._construct_static_features(static_features, id_column=id_column)
@@ -419,10 +419,7 @@ class TimeSeriesDataFrame(pd.DataFrame, TimeSeriesDataFrameDeprecatedMixin):
419
419
  def item_ids(self) -> pd.Index:
420
420
  return self.index.unique(level=ITEMID)
421
421
 
422
- @property
423
- def static_features(self):
424
- return self._static_features
425
-
422
+ @classmethod
426
423
  def _construct_static_features(
427
424
  cls,
428
425
  static_features: Union[pd.DataFrame, str, Path],
@@ -443,6 +440,10 @@ class TimeSeriesDataFrame(pd.DataFrame, TimeSeriesDataFrameDeprecatedMixin):
443
440
  static_features.rename(columns={id_column: ITEMID}, inplace=True)
444
441
  return static_features
445
442
 
443
+ @property
444
+ def static_features(self):
445
+ return self._static_features
446
+
446
447
  @static_features.setter
447
448
  def static_features(self, value: Optional[pd.DataFrame]):
448
449
  # if the current item index is not a multiindex, then we are dealing with a single
@@ -50,28 +50,28 @@ EXPERIMENTAL_METRICS = {
50
50
  def check_get_evaluation_metric(
51
51
  eval_metric: Union[str, TimeSeriesScorer, Type[TimeSeriesScorer], None] = None
52
52
  ) -> TimeSeriesScorer:
53
+ scorer: TimeSeriesScorer
53
54
  if isinstance(eval_metric, TimeSeriesScorer):
54
- eval_metric = eval_metric
55
+ scorer = eval_metric
55
56
  elif isinstance(eval_metric, type) and issubclass(eval_metric, TimeSeriesScorer):
56
57
  # e.g., user passed `eval_metric=CustomMetric` instead of `eval_metric=CustomMetric()`
57
- eval_metric = eval_metric()
58
+ scorer = eval_metric()
58
59
  elif isinstance(eval_metric, str):
59
- eval_metric = DEPRECATED_METRICS.get(eval_metric, eval_metric)
60
- metric_name = eval_metric.upper()
60
+ metric_name = DEPRECATED_METRICS.get(eval_metric, eval_metric).upper()
61
61
  if metric_name in AVAILABLE_METRICS:
62
- eval_metric = AVAILABLE_METRICS[metric_name]()
62
+ scorer = AVAILABLE_METRICS[metric_name]()
63
63
  elif metric_name in EXPERIMENTAL_METRICS:
64
- eval_metric = EXPERIMENTAL_METRICS[metric_name]()
64
+ scorer = EXPERIMENTAL_METRICS[metric_name]()
65
65
  else:
66
66
  raise ValueError(
67
67
  f"Time series metric {eval_metric} not supported. Available metrics are:\n"
68
68
  f"{pformat(sorted(AVAILABLE_METRICS.keys()))}"
69
69
  )
70
70
  elif eval_metric is None:
71
- eval_metric = AVAILABLE_METRICS[DEFAULT_METRIC_NAME]()
71
+ scorer = AVAILABLE_METRICS[DEFAULT_METRIC_NAME]()
72
72
  else:
73
73
  raise ValueError(
74
74
  f"eval_metric must be of type str, TimeSeriesScorer or None "
75
75
  f"(received eval_metric = {eval_metric} of type {type(eval_metric)})"
76
76
  )
77
- return eval_metric
77
+ return scorer
@@ -161,7 +161,7 @@ class TimeSeriesScorer:
161
161
  @staticmethod
162
162
  def _safemean(array: Union[np.ndarray, pd.Series]) -> float:
163
163
  """Compute mean of a numpy array-like object, ignoring inf, -inf and nan values."""
164
- return np.mean(array[np.isfinite(array)])
164
+ return float(np.mean(array[np.isfinite(array)]))
165
165
 
166
166
  @staticmethod
167
167
  def _get_point_forecast_score_inputs(
@@ -248,7 +248,7 @@ class MASE(TimeSeriesScorer):
248
248
 
249
249
  num_items = len(self._past_abs_seasonal_error)
250
250
  # Reshape abs errors into [num_items, prediction_length] to normalize per item without groupby
251
- abs_errors = np.abs(y_true.values - y_pred.values).reshape([num_items, -1])
251
+ abs_errors = np.abs(y_true.to_numpy() - y_pred.to_numpy()).reshape([num_items, -1])
252
252
  return self._safemean(abs_errors / self._past_abs_seasonal_error.values[:, None])
253
253
 
254
254
 
@@ -308,7 +308,7 @@ class RMSSE(TimeSeriesScorer):
308
308
 
309
309
  num_items = len(self._past_squared_seasonal_error)
310
310
  # Reshape squared errors into [num_items, prediction_length] to normalize per item without groupby
311
- squared_errors = ((y_true.values - y_pred.values) ** 2.0).reshape([num_items, -1])
311
+ squared_errors = ((y_true.to_numpy() - y_pred.to_numpy()) ** 2.0).reshape([num_items, -1])
312
312
  return np.sqrt(self._safemean(squared_errors / self._past_squared_seasonal_error.values[:, None]))
313
313
 
314
314
 
@@ -335,7 +335,9 @@ class RMSLE(TimeSeriesScorer):
335
335
  - `Scikit-learn: <https://scikit-learn.org/stable/modules/model_evaluation.html#mean-squared-log-error>`_
336
336
  """
337
337
 
338
- def compute_metric(self, data_future, predictions, target, **kwargs):
338
+ def compute_metric(
339
+ self, data_future: TimeSeriesDataFrame, predictions: TimeSeriesDataFrame, target: str = "target", **kwargs
340
+ ) -> float:
339
341
  y_true, y_pred = self._get_point_forecast_score_inputs(data_future, predictions, target=target)
340
342
  y_pred = np.clip(y_pred, a_min=0.0, a_max=None)
341
343
 
@@ -399,6 +401,7 @@ class WCD(TimeSeriesScorer):
399
401
 
400
402
  def _fast_cumsum(self, y: np.ndarray) -> np.ndarray:
401
403
  """Compute the cumulative sum for each consecutive `prediction_length` items in the array."""
404
+ assert self.num_items is not None, "Make sure to call `save_past_metrics` before `compute_metric`"
402
405
  y = y.reshape(self.num_items, -1)
403
406
  return np.nancumsum(y, axis=1).ravel()
404
407
 
@@ -3,7 +3,7 @@ import os
3
3
  import re
4
4
  import time
5
5
  from contextlib import nullcontext
6
- from typing import Dict, List, Optional, Tuple, Union
6
+ from typing import Any, Dict, List, Optional, Tuple, Union
7
7
 
8
8
  import pandas as pd
9
9
 
@@ -138,6 +138,7 @@ class AbstractTimeSeriesModel(AbstractModel):
138
138
  self.target_scaler: Optional[LocalTargetScaler] = None
139
139
  self.covariate_scaler: Optional[CovariateScaler] = None
140
140
  self.covariate_regressor: Optional[CovariateRegressor] = None
141
+ self.fit_time: Optional[float]
141
142
 
142
143
  def __repr__(self) -> str:
143
144
  return self.name
@@ -389,7 +390,7 @@ class AbstractTimeSeriesModel(AbstractModel):
389
390
 
390
391
  def predict(
391
392
  self,
392
- data: Union[TimeSeriesDataFrame, Dict[str, TimeSeriesDataFrame]],
393
+ data: Union[TimeSeriesDataFrame, Dict[str, Optional[TimeSeriesDataFrame]]],
393
394
  known_covariates: Optional[TimeSeriesDataFrame] = None,
394
395
  **kwargs,
395
396
  ) -> TimeSeriesDataFrame:
@@ -402,7 +403,7 @@ class AbstractTimeSeriesModel(AbstractModel):
402
403
 
403
404
  Parameters
404
405
  ----------
405
- data: Union[TimeSeriesDataFrame, Dict[str, TimeSeriesDataFrame]]
406
+ data: Union[TimeSeriesDataFrame, Dict[str, Optional[TimeSeriesDataFrame]]]
406
407
  The dataset where each time series is the "context" for predictions. For ensemble models that depend on
407
408
  the predictions of other models, this method may accept a dictionary of previous models' predictions.
408
409
  known_covariates : Optional[TimeSeriesDataFrame]
@@ -543,8 +544,12 @@ class AbstractTimeSeriesModel(AbstractModel):
543
544
  return False
544
545
 
545
546
  def hyperparameter_tune(
546
- self, hyperparameter_tune_kwargs="auto", hpo_executor: HpoExecutor = None, time_limit: float = None, **kwargs
547
- ):
547
+ self,
548
+ hyperparameter_tune_kwargs: Union[str, dict] = "auto",
549
+ hpo_executor: Optional[HpoExecutor] = None,
550
+ time_limit: Optional[float] = None,
551
+ **kwargs,
552
+ ) -> Tuple[Dict[str, Any], Dict[str, Any]]:
548
553
  if hpo_executor is None:
549
554
  hpo_executor = self._get_default_hpo_executor()
550
555
  default_num_trials = kwargs.pop("default_num_trials", None)
@@ -20,7 +20,7 @@ class AbstractTimeSeriesEnsembleModel(AbstractTimeSeriesModel):
20
20
  self,
21
21
  predictions_per_window: Dict[str, List[TimeSeriesDataFrame]],
22
22
  data_per_window: List[TimeSeriesDataFrame],
23
- time_limit: Optional[int] = None,
23
+ time_limit: Optional[float] = None,
24
24
  **kwargs,
25
25
  ):
26
26
  """Fit ensemble model given predictions of candidate base models and the true data.
@@ -67,7 +67,7 @@ class AbstractTimeSeriesEnsembleModel(AbstractTimeSeriesModel):
67
67
  """
68
68
  raise NotImplementedError
69
69
 
70
- def predict(self, data: Dict[str, TimeSeriesDataFrame], **kwargs) -> TimeSeriesDataFrame:
70
+ def predict(self, data: Dict[str, Optional[TimeSeriesDataFrame]], **kwargs) -> TimeSeriesDataFrame:
71
71
  raise NotImplementedError
72
72
 
73
73
  def remap_base_models(self, model_refit_map: Dict[str, str]) -> None:
@@ -143,7 +143,7 @@ class TimeSeriesGreedyEnsemble(AbstractTimeSeriesEnsembleModel):
143
143
  def model_weights(self) -> np.ndarray:
144
144
  return np.array(list(self.model_to_weight.values()), dtype=np.float64)
145
145
 
146
- def predict(self, data: Dict[str, TimeSeriesDataFrame], **kwargs) -> TimeSeriesDataFrame:
146
+ def predict(self, data: Dict[str, Optional[TimeSeriesDataFrame]], **kwargs) -> TimeSeriesDataFrame:
147
147
  if set(data.keys()) != set(self.model_names):
148
148
  raise ValueError(
149
149
  f"Set of models given for prediction in {self.name} differ from those provided during initialization."
@@ -179,7 +179,7 @@ def get_default_hps(key):
179
179
 
180
180
 
181
181
  def get_preset_models(
182
- freq: str,
182
+ freq: Optional[str],
183
183
  prediction_length: int,
184
184
  path: str,
185
185
  eval_metric: TimeSeriesScorer,
@@ -188,7 +188,7 @@ def get_preset_models(
188
188
  hyperparameter_tune: bool,
189
189
  metadata: CovariateMetadata,
190
190
  all_assigned_names: List[str],
191
- excluded_model_types: List[str],
191
+ excluded_model_types: Optional[List[str]],
192
192
  multi_window: bool = False,
193
193
  **kwargs,
194
194
  ):
@@ -1445,7 +1445,7 @@ class TimeSeriesPredictor(TimeSeriesPredictorDeprecatedMixin):
1445
1445
  past_data, known_covariates = test_data.get_model_inputs_for_scoring(
1446
1446
  prediction_length=self.prediction_length, known_covariates_names=trainer.metadata.known_covariates
1447
1447
  )
1448
- pred_proba_dict_test: Dict[str, TimeSeriesDataFrame] = trainer.get_model_pred_dict(
1448
+ pred_proba_dict_test, _ = trainer.get_model_pred_dict(
1449
1449
  base_model_names, data=past_data, known_covariates=known_covariates
1450
1450
  )
1451
1451
 
@@ -13,6 +13,9 @@ class AbstractWindowSplitter:
13
13
  self.prediction_length = prediction_length
14
14
  self.num_val_windows = num_val_windows
15
15
 
16
+ def split(self, data: TimeSeriesDataFrame) -> Iterator[Tuple[TimeSeriesDataFrame, TimeSeriesDataFrame]]:
17
+ raise NotImplementedError
18
+
16
19
 
17
20
  class ExpandingWindowSplitter(AbstractWindowSplitter):
18
21
  """For each train / validation split, training data includes all available past data.
@@ -66,7 +66,7 @@ class SimpleAbstractTrainer:
66
66
  """
67
67
  return self.get_model_names() + list(self._extra_banned_names)
68
68
 
69
- def get_models_attribute_dict(self, attribute: str, models: List[str] = None) -> Dict[str, Any]:
69
+ def get_models_attribute_dict(self, attribute: str, models: Optional[List[str]] = None) -> Dict[str, Any]:
70
70
  """Get an attribute from the `model_graph` for each of the model names
71
71
  specified. If `models` is none, the attribute will be returned for all models"""
72
72
  results = {}
@@ -150,15 +150,15 @@ class SimpleAbstractTrainer:
150
150
  model_type: Optional[Type[AbstractModel]] = None,
151
151
  ) -> AbstractTimeSeriesModel:
152
152
  if isinstance(model_name, AbstractModel):
153
+ assert isinstance(model_name, AbstractTimeSeriesModel)
153
154
  return model_name
154
155
  if model_name in self.models.keys():
155
156
  return self.models[model_name]
156
157
 
157
- if path is None:
158
- path = self.get_model_attribute(model=model_name, attribute="path")
159
- if model_type is None:
160
- model_type = self.get_model_attribute(model=model_name, attribute="type")
161
- return model_type.load(path=os.path.join(self.path, path), reset_paths=self.reset_paths)
158
+ path_ = path if path is not None else self.get_model_attribute(model=model_name, attribute="path")
159
+ type_ = model_type if model_type is not None else self.get_model_attribute(model=model_name, attribute="type")
160
+
161
+ return type_.load(path=os.path.join(self.path, path_), reset_paths=self.reset_paths)
162
162
 
163
163
  def construct_model_templates(self, hyperparameters: Union[str, Dict[str, Any]], **kwargs):
164
164
  raise NotImplementedError
@@ -177,7 +177,7 @@ class SimpleAbstractTrainer:
177
177
  minimum_model_set = [m for m in minimum_model_set if m != model]
178
178
  return minimum_model_set
179
179
 
180
- def get_models_info(self, models: List[str] = None) -> Dict[str, Any]:
180
+ def get_models_info(self, models: Optional[List[str]] = None) -> Dict[str, Any]:
181
181
  if models is None:
182
182
  models = self.get_model_names()
183
183
  model_info_dict = dict()
@@ -212,7 +212,7 @@ class SimpleAbstractTrainer:
212
212
  save_json.save(path=os.path.join(self.path, self.trainer_info_json_name), obj=info)
213
213
  return info
214
214
 
215
- def get_model_best(self, *args, **kwargs) -> AbstractModel:
215
+ def get_model_best(self, *args, **kwargs) -> str:
216
216
  raise NotImplementedError
217
217
 
218
218
  def get_info(self, include_model_info: bool = False) -> Dict[str, Any]:
@@ -254,7 +254,7 @@ class AbstractTimeSeriesTrainer(SimpleAbstractTrainer):
254
254
  def __init__(
255
255
  self,
256
256
  path: str,
257
- prediction_length: Optional[int] = 1,
257
+ prediction_length: int = 1,
258
258
  eval_metric: Union[str, TimeSeriesScorer, None] = None,
259
259
  eval_metric_seasonal_period: Optional[int] = None,
260
260
  save_data: bool = True,
@@ -347,7 +347,7 @@ class AbstractTimeSeriesTrainer(SimpleAbstractTrainer):
347
347
  def _add_model(
348
348
  self,
349
349
  model: AbstractTimeSeriesModel,
350
- base_models: List[str] = None,
350
+ base_models: Optional[List[str]] = None,
351
351
  ):
352
352
  """Add a model to the model graph of the trainer. If the model is an ensemble, also add
353
353
  information about dependencies to the model graph (list of models specified via ``base_models``).
@@ -400,7 +400,7 @@ class AbstractTimeSeriesTrainer(SimpleAbstractTrainer):
400
400
 
401
401
  return levels
402
402
 
403
- def get_model_best(self) -> str:
403
+ def get_model_best(self, *args, **kwargs) -> str:
404
404
  """Return the name of the best model by model performance on the validation set."""
405
405
  models = self.get_model_names()
406
406
  if not models:
@@ -642,6 +642,9 @@ class AbstractTimeSeriesTrainer(SimpleAbstractTrainer):
642
642
  )
643
643
  logger.info(fit_log_message)
644
644
  with tqdm.external_write_mode():
645
+ assert hyperparameter_tune_kwargs is not None, (
646
+ "`hyperparameter_tune_kwargs` must be provided if hyperparameters contain a search space"
647
+ )
645
648
  model_names_trained += self.tune_model_hyperparameters(
646
649
  model,
647
650
  time_limit=time_left_for_model,
@@ -760,7 +763,7 @@ class AbstractTimeSeriesTrainer(SimpleAbstractTrainer):
760
763
  for window_idx, data in enumerate(data_per_window):
761
764
  predictions = ensemble.predict({n: model_preds[n][window_idx] for n in ensemble.model_names})
762
765
  score_per_fold.append(self._score_with_predictions(data, predictions))
763
- ensemble.val_score = np.mean(score_per_fold)
766
+ ensemble.val_score = float(np.mean(score_per_fold, dtype=np.float64))
764
767
 
765
768
  self._log_scores_and_times(
766
769
  val_score=ensemble.val_score,
@@ -814,7 +817,6 @@ class AbstractTimeSeriesTrainer(SimpleAbstractTrainer):
814
817
  model_names=model_names,
815
818
  data=past_data,
816
819
  known_covariates=known_covariates,
817
- record_pred_time=True,
818
820
  raise_exception_if_failed=False,
819
821
  use_cache=use_cache,
820
822
  )
@@ -934,14 +936,17 @@ class AbstractTimeSeriesTrainer(SimpleAbstractTrainer):
934
936
  **kwargs,
935
937
  ) -> TimeSeriesDataFrame:
936
938
  model_name = self._get_model_for_prediction(model)
937
- model_pred_dict = self.get_model_pred_dict(
939
+ model_pred_dict, _ = self.get_model_pred_dict(
938
940
  model_names=[model_name],
939
941
  data=data,
940
942
  known_covariates=known_covariates,
941
943
  use_cache=use_cache,
942
944
  random_seed=random_seed,
943
945
  )
944
- return model_pred_dict[model_name]
946
+ predictions = model_pred_dict[model_name]
947
+ if predictions is None:
948
+ raise ValueError(f"Model {model_name} failed to predict. Please check the model's logs.")
949
+ return predictions
945
950
 
946
951
  def _score_with_predictions(
947
952
  self,
@@ -981,10 +986,10 @@ class AbstractTimeSeriesTrainer(SimpleAbstractTrainer):
981
986
  prediction_length=self.prediction_length, known_covariates_names=self.metadata.known_covariates
982
987
  )
983
988
  predictions = self.predict(data=past_data, known_covariates=known_covariates, model=model, use_cache=use_cache)
984
- if not isinstance(metrics, list): # a single metric is provided
985
- metrics = [metrics]
989
+
990
+ metrics_ = [metrics] if not isinstance(metrics, list) else metrics
986
991
  scores_dict = {}
987
- for metric in metrics:
992
+ for metric in metrics_:
988
993
  eval_metric = self.eval_metric if metric is None else check_get_evaluation_metric(metric)
989
994
  scores_dict[eval_metric.name] = self._score_with_predictions(
990
995
  data=data, predictions=predictions, metric=eval_metric
@@ -1034,6 +1039,10 @@ class AbstractTimeSeriesTrainer(SimpleAbstractTrainer):
1034
1039
  "permutation": PermutationFeatureImportanceTransform,
1035
1040
  "naive": ConstantReplacementFeatureImportanceTransform,
1036
1041
  }.get(method)
1042
+ assert importance_transform_type is not None, (
1043
+ f"Invalid feature importance method {method}. Valid methods are 'permutation' and 'naive',"
1044
+ )
1045
+
1037
1046
  importance_transform = importance_transform_type(
1038
1047
  covariate_metadata=self.metadata,
1039
1048
  prediction_length=self.prediction_length,
@@ -1050,7 +1059,7 @@ class AbstractTimeSeriesTrainer(SimpleAbstractTrainer):
1050
1059
  for n in range(num_iterations):
1051
1060
  if subsample_size < data.num_items:
1052
1061
  item_ids_sampled = data.item_ids.to_series().sample(subsample_size) # noqa
1053
- data_sample = data.query("item_id in @item_ids_sampled")
1062
+ data_sample: TimeSeriesDataFrame = data.query("item_id in @item_ids_sampled") # type: ignore
1054
1063
  else:
1055
1064
  data_sample = data
1056
1065
 
@@ -1094,7 +1103,7 @@ class AbstractTimeSeriesTrainer(SimpleAbstractTrainer):
1094
1103
 
1095
1104
  return importance_df
1096
1105
 
1097
- def _model_uses_feature(self, model: Optional[Union[str, AbstractTimeSeriesModel]], feature: str) -> bool:
1106
+ def _model_uses_feature(self, model: Union[str, AbstractTimeSeriesModel], feature: str) -> bool:
1098
1107
  """Check if the given model uses the given feature."""
1099
1108
  models_with_ancestors = set(self.get_minimum_model_set(model))
1100
1109
 
@@ -1138,7 +1147,7 @@ class AbstractTimeSeriesTrainer(SimpleAbstractTrainer):
1138
1147
  self,
1139
1148
  model: Union[str, AbstractTimeSeriesModel],
1140
1149
  data: TimeSeriesDataFrame,
1141
- model_pred_dict: Dict[str, TimeSeriesDataFrame],
1150
+ model_pred_dict: Dict[str, Optional[TimeSeriesDataFrame]],
1142
1151
  known_covariates: Optional[TimeSeriesDataFrame] = None,
1143
1152
  ) -> TimeSeriesDataFrame:
1144
1153
  """Generate predictions using the given model.
@@ -1147,15 +1156,15 @@ class AbstractTimeSeriesTrainer(SimpleAbstractTrainer):
1147
1156
  """
1148
1157
  if isinstance(model, str):
1149
1158
  model = self.load_model(model)
1150
- data = self._get_inputs_to_model(model=model, data=data, model_pred_dict=model_pred_dict)
1151
- return model.predict(data, known_covariates=known_covariates)
1159
+ model_inputs = self._get_inputs_to_model(model=model, data=data, model_pred_dict=model_pred_dict)
1160
+ return model.predict(model_inputs, known_covariates=known_covariates)
1152
1161
 
1153
1162
  def _get_inputs_to_model(
1154
1163
  self,
1155
- model: str,
1164
+ model: Union[str, AbstractTimeSeriesModel],
1156
1165
  data: TimeSeriesDataFrame,
1157
- model_pred_dict: Dict[str, TimeSeriesDataFrame],
1158
- ) -> Union[TimeSeriesDataFrame, Dict[str, TimeSeriesDataFrame]]:
1166
+ model_pred_dict: Dict[str, Optional[TimeSeriesDataFrame]],
1167
+ ) -> Union[TimeSeriesDataFrame, Dict[str, Optional[TimeSeriesDataFrame]]]:
1159
1168
  """Get the first argument that should be passed to model.predict.
1160
1169
 
1161
1170
  This method assumes that model_pred_dict contains the predictions of all base models, if model is an ensemble.
@@ -1174,11 +1183,10 @@ class AbstractTimeSeriesTrainer(SimpleAbstractTrainer):
1174
1183
  model_names: List[str],
1175
1184
  data: TimeSeriesDataFrame,
1176
1185
  known_covariates: Optional[TimeSeriesDataFrame] = None,
1177
- record_pred_time: bool = False,
1178
1186
  raise_exception_if_failed: bool = True,
1179
1187
  use_cache: bool = True,
1180
1188
  random_seed: Optional[int] = None,
1181
- ) -> Union[Dict[str, TimeSeriesDataFrame], Tuple[Dict[str, TimeSeriesDataFrame], Dict[str, float]]]:
1189
+ ) -> Tuple[Dict[str, Optional[TimeSeriesDataFrame]], Dict[str, float]]:
1182
1190
  """Return a dictionary with predictions of all models for the given dataset.
1183
1191
 
1184
1192
  Parameters
@@ -1204,14 +1212,14 @@ class AbstractTimeSeriesTrainer(SimpleAbstractTrainer):
1204
1212
  model_pred_dict, pred_time_dict_marginal = self._get_cached_pred_dicts(dataset_hash)
1205
1213
  else:
1206
1214
  model_pred_dict = {}
1207
- pred_time_dict_marginal = {}
1215
+ pred_time_dict_marginal: Dict[str, Any] = {}
1208
1216
 
1209
1217
  model_set = set()
1210
1218
  for model_name in model_names:
1211
1219
  model_set.update(self.get_minimum_model_set(model_name))
1212
1220
  if len(model_set) > 1:
1213
1221
  model_to_level = self._get_model_levels()
1214
- model_set = sorted(model_set, key=model_to_level.get)
1222
+ model_set = sorted(model_set, key=model_to_level.get) # type: ignore
1215
1223
  logger.debug(f"Prediction order: {model_set}")
1216
1224
 
1217
1225
  failed_models = []
@@ -1239,16 +1247,16 @@ class AbstractTimeSeriesTrainer(SimpleAbstractTrainer):
1239
1247
  raise RuntimeError(f"Following models failed to predict: {failed_models}")
1240
1248
  if self.cache_predictions and use_cache:
1241
1249
  self._save_cached_pred_dicts(
1242
- dataset_hash, model_pred_dict=model_pred_dict, pred_time_dict=pred_time_dict_marginal
1250
+ dataset_hash, # type: ignore
1251
+ model_pred_dict=model_pred_dict,
1252
+ pred_time_dict=pred_time_dict_marginal,
1243
1253
  )
1244
1254
  pred_time_dict_total = self._get_total_pred_time_from_marginal(pred_time_dict_marginal)
1245
1255
 
1246
1256
  final_model_pred_dict = {model_name: model_pred_dict[model_name] for model_name in model_names}
1247
1257
  final_pred_time_dict_total = {model_name: pred_time_dict_total[model_name] for model_name in model_names}
1248
- if record_pred_time:
1249
- return final_model_pred_dict, final_pred_time_dict_total
1250
- else:
1251
- return final_model_pred_dict
1258
+
1259
+ return final_model_pred_dict, final_pred_time_dict_total
1252
1260
 
1253
1261
  def _get_total_pred_time_from_marginal(self, pred_time_dict_marginal: Dict[str, float]) -> Dict[str, float]:
1254
1262
  pred_time_dict_total = defaultdict(float)
@@ -1270,7 +1278,9 @@ class AbstractTimeSeriesTrainer(SimpleAbstractTrainer):
1270
1278
  combined_hash = hash_pandas_df(data) + hash_pandas_df(known_covariates) + hash_pandas_df(data.static_features)
1271
1279
  return combined_hash
1272
1280
 
1273
- def _get_cached_pred_dicts(self, dataset_hash: str) -> Tuple[Dict[str, TimeSeriesDataFrame], Dict[str, float]]:
1281
+ def _get_cached_pred_dicts(
1282
+ self, dataset_hash: str
1283
+ ) -> Tuple[Dict[str, Optional[TimeSeriesDataFrame]], Dict[str, float]]:
1274
1284
  """Load cached predictions for given dataset_hash from disk, if possible. Otherwise returns empty dicts."""
1275
1285
  if self._cached_predictions_path.exists():
1276
1286
  cached_predictions = load_pkl.load(str(self._cached_predictions_path))
@@ -1286,7 +1296,10 @@ class AbstractTimeSeriesTrainer(SimpleAbstractTrainer):
1286
1296
  return {}, {}
1287
1297
 
1288
1298
  def _save_cached_pred_dicts(
1289
- self, dataset_hash: str, model_pred_dict: Dict[str, TimeSeriesDataFrame], pred_time_dict: Dict[str, float]
1299
+ self,
1300
+ dataset_hash: str,
1301
+ model_pred_dict: Dict[str, Optional[TimeSeriesDataFrame]],
1302
+ pred_time_dict: Dict[str, float],
1290
1303
  ) -> None:
1291
1304
  # TODO: Save separate file for each dataset if _cached_predictions file grows large?
1292
1305
  if self._cached_predictions_path.exists():
@@ -1315,7 +1328,7 @@ class AbstractTimeSeriesTrainer(SimpleAbstractTrainer):
1315
1328
  self,
1316
1329
  train_data: Optional[TimeSeriesDataFrame] = None,
1317
1330
  val_data: Optional[TimeSeriesDataFrame] = None,
1318
- models: List[str] = None,
1331
+ models: Optional[List[str]] = None,
1319
1332
  ) -> List[str]:
1320
1333
  train_data = train_data or self.load_train_data()
1321
1334
  val_data = val_data or self.load_val_data()
@@ -1325,7 +1338,7 @@ class AbstractTimeSeriesTrainer(SimpleAbstractTrainer):
1325
1338
  models = self.get_model_names()
1326
1339
 
1327
1340
  model_to_level = self._get_model_levels()
1328
- models_sorted_by_level = sorted(models, key=model_to_level.get)
1341
+ models_sorted_by_level = sorted(models, key=model_to_level.get) # type: ignore
1329
1342
 
1330
1343
  model_refit_map = {}
1331
1344
  models_trained_full = []
@@ -1392,7 +1405,7 @@ class AbstractTimeSeriesTrainer(SimpleAbstractTrainer):
1392
1405
  return copy.deepcopy(self.model_refit_map)
1393
1406
 
1394
1407
  def construct_model_templates(
1395
- self, hyperparameters: Union[str, Dict[str, Any]], multi_window: bool = False, **kwargs
1408
+ self, hyperparameters: Optional[Union[str, Dict[str, Any]]], multi_window: bool = False, **kwargs
1396
1409
  ) -> List[AbstractTimeSeriesModel]:
1397
1410
  """Constructs a list of unfit models based on the hyperparameters dict."""
1398
1411
  raise NotImplementedError
@@ -14,6 +14,7 @@ class AutoTimeSeriesTrainer(AbstractTimeSeriesTrainer):
14
14
  eval_metric_seasonal_period = kwargs.pop("eval_metric", self.eval_metric_seasonal_period)
15
15
  quantile_levels = kwargs.pop("quantile_levels", self.quantile_levels)
16
16
  hyperparameter_tune = kwargs.get("hyperparameter_tune", False)
17
+
17
18
  return get_preset_models(
18
19
  path=path,
19
20
  eval_metric=eval_metric,
@@ -1,3 +1,4 @@
1
1
  """This is the autogluon version file."""
2
- __version__ = '1.2.1b20250114'
2
+
3
+ __version__ = "1.2.1b20250116"
3
4
  __lite__ = False
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: autogluon.timeseries
3
- Version: 1.2.1b20250114
3
+ Version: 1.2.1b20250116
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
@@ -9,17 +9,17 @@ transformers[sentencepiece]<5,>=4.38.0
9
9
  accelerate<1.0,>=0.34.0
10
10
  gluonts<0.17,>=0.15.0
11
11
  networkx<4,>=3.0
12
- statsforecast<1.8,>=1.7.0
13
- mlforecast==0.13.4
14
- utilsforecast<0.2.5,>=0.2.3
15
- coreforecast==0.0.12
12
+ statsforecast<2.0.1,>=1.7.0
13
+ mlforecast<0.14,>0.13
14
+ utilsforecast<0.2.11,>=0.2.3
15
+ coreforecast<0.0.16,>=0.0.12
16
16
  fugue>=0.9.0
17
17
  tqdm<5,>=4.38
18
18
  orjson~=3.9
19
19
  tensorboard<3,>=2.9
20
- autogluon.core[raytune]==1.2.1b20250114
21
- autogluon.common==1.2.1b20250114
22
- autogluon.tabular[catboost,lightgbm,xgboost]==1.2.1b20250114
20
+ autogluon.core[raytune]==1.2.1b20250116
21
+ autogluon.common==1.2.1b20250116
22
+ autogluon.tabular[catboost,lightgbm,xgboost]==1.2.1b20250116
23
23
 
24
24
  [all]
25
25