autogluon.timeseries 0.7.0b20230329__py3-none-any.whl → 0.7.0b20230331__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.

Files changed (18) hide show
  1. autogluon/timeseries/__init__.py +0 -17
  2. autogluon/timeseries/models/local/abstract_local_model.py +15 -1
  3. autogluon/timeseries/models/local/statsforecast.py +1 -2
  4. autogluon/timeseries/models/presets.py +0 -14
  5. autogluon/timeseries/version.py +1 -1
  6. {autogluon.timeseries-0.7.0b20230329.dist-info → autogluon.timeseries-0.7.0b20230331.dist-info}/METADATA +4 -11
  7. {autogluon.timeseries-0.7.0b20230329.dist-info → autogluon.timeseries-0.7.0b20230331.dist-info}/RECORD +14 -18
  8. autogluon/timeseries/models/sktime/__init__.py +0 -20
  9. autogluon/timeseries/models/sktime/abstract_sktime.py +0 -185
  10. autogluon/timeseries/models/sktime/models.py +0 -408
  11. autogluon/timeseries/utils/hashing.py +0 -20
  12. /autogluon.timeseries-0.7.0b20230329-py3.8-nspkg.pth → /autogluon.timeseries-0.7.0b20230331-py3.8-nspkg.pth +0 -0
  13. {autogluon.timeseries-0.7.0b20230329.dist-info → autogluon.timeseries-0.7.0b20230331.dist-info}/LICENSE +0 -0
  14. {autogluon.timeseries-0.7.0b20230329.dist-info → autogluon.timeseries-0.7.0b20230331.dist-info}/NOTICE +0 -0
  15. {autogluon.timeseries-0.7.0b20230329.dist-info → autogluon.timeseries-0.7.0b20230331.dist-info}/WHEEL +0 -0
  16. {autogluon.timeseries-0.7.0b20230329.dist-info → autogluon.timeseries-0.7.0b20230331.dist-info}/namespace_packages.txt +0 -0
  17. {autogluon.timeseries-0.7.0b20230329.dist-info → autogluon.timeseries-0.7.0b20230331.dist-info}/top_level.txt +0 -0
  18. {autogluon.timeseries-0.7.0b20230329.dist-info → autogluon.timeseries-0.7.0b20230331.dist-info}/zip-safe +0 -0
@@ -24,23 +24,6 @@ except ImportError:
24
24
  pass
25
25
 
26
26
 
27
- SKTIME_INSTALLED = False
28
- try:
29
- import pmdarima
30
- import sktime
31
- import tbats
32
-
33
- if parse("0.16") > parse(sktime.__version__) >= parse("0.14"):
34
- SKTIME_INSTALLED = True
35
- else:
36
- warnings.warn(
37
- "autogluon.timeseries depends on sktime version >=0.13.1 and <0.14, although "
38
- f"{sktime.__version__} was found. sktime features will be disabled."
39
- )
40
- except ImportError:
41
- pass
42
-
43
-
44
27
  from .dataset import TimeSeriesDataFrame
45
28
  from .evaluator import TimeSeriesEvaluator
46
29
  from .predictor import TimeSeriesPredictor
@@ -1,3 +1,4 @@
1
+ import hashlib
1
2
  import logging
2
3
  import re
3
4
  from multiprocessing import cpu_count
@@ -8,13 +9,26 @@ from joblib import Parallel, delayed
8
9
 
9
10
  from autogluon.timeseries.dataset.ts_dataframe import ITEMID, TIMESTAMP, TimeSeriesDataFrame
10
11
  from autogluon.timeseries.models.abstract import AbstractTimeSeriesModel
11
- from autogluon.timeseries.utils.hashing import hash_ts_dataframe_items
12
12
  from autogluon.timeseries.utils.seasonality import get_seasonality
13
13
  from autogluon.timeseries.utils.warning_filters import statsmodels_joblib_warning_filter
14
14
 
15
15
  logger = logging.getLogger(__name__)
16
16
 
17
17
 
18
+ def hash_ts_dataframe_items(ts_dataframe: TimeSeriesDataFrame) -> pd.Series:
19
+ """Hash each time series in the dataset to a 32-character hex string.
20
+
21
+ Hash is computed based on the timestamps and values of the time series (item_id is ignored).
22
+
23
+ This means that any model that doesn't use static features will make identical predictions for two time series
24
+ with the same hash value (assuming no collisions).
25
+ """
26
+ df_with_timestamp = ts_dataframe.reset_index(level=TIMESTAMP)
27
+ hash_per_timestep = pd.util.hash_pandas_object(df_with_timestamp, index=False)
28
+ # groupby preserves the order of the timesteps
29
+ return hash_per_timestep.groupby(level=ITEMID, sort=False).apply(lambda x: hashlib.md5(x.values).hexdigest())
30
+
31
+
18
32
  class AbstractLocalModel(AbstractTimeSeriesModel):
19
33
  allowed_local_model_args: List[str] = []
20
34
  # Use 50% of the cores since some models rely on parallel ops and are actually slower if n_jobs=-1
@@ -5,8 +5,7 @@ import pandas as pd
5
5
 
6
6
  from autogluon.core.utils.exceptions import TimeLimitExceeded
7
7
  from autogluon.timeseries.dataset.ts_dataframe import ITEMID, TIMESTAMP, TimeSeriesDataFrame
8
- from autogluon.timeseries.models.local.abstract_local_model import AbstractLocalModel
9
- from autogluon.timeseries.utils.hashing import hash_ts_dataframe_items
8
+ from autogluon.timeseries.models.local.abstract_local_model import AbstractLocalModel, hash_ts_dataframe_items
10
9
  from autogluon.timeseries.utils.warning_filters import statsmodels_warning_filter
11
10
 
12
11
  logger = logging.getLogger(__name__)
@@ -60,17 +60,6 @@ if agts.MXNET_INSTALLED:
60
60
  )
61
61
  )
62
62
 
63
- if agts.SKTIME_INSTALLED:
64
- from .sktime import ARIMASktimeModel, AutoARIMASktimeModel, AutoETSSktimeModel
65
-
66
- MODEL_TYPES.update(
67
- dict(
68
- ARIMASktime=ARIMASktimeModel,
69
- AutoARIMASktime=AutoARIMASktimeModel,
70
- AutoETSSktime=AutoETSSktimeModel,
71
- )
72
- )
73
-
74
63
  DEFAULT_MODEL_NAMES = {v: k for k, v in MODEL_TYPES.items()}
75
64
  DEFAULT_MODEL_PRIORITY = dict(
76
65
  Naive=100,
@@ -87,12 +76,9 @@ DEFAULT_MODEL_PRIORITY = dict(
87
76
  AutoETS=70,
88
77
  DynamicOptimizedTheta=60,
89
78
  # Models below are not included in any presets
90
- AutoETSSktime=60,
91
- ARIMASktime=50,
92
79
  DeepARMXNet=50,
93
80
  SimpleFeedForwardMXNet=30,
94
81
  TemporalFusionTransformerMXNet=50,
95
- AutoARIMASktime=20,
96
82
  MQCNNMXNet=10,
97
83
  MQRNNMXNet=10,
98
84
  )
@@ -1,3 +1,3 @@
1
1
  """This is the autogluon version file."""
2
- __version__ = '0.7.0b20230329'
2
+ __version__ = '0.7.0b20230331'
3
3
  __lite__ = False
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: autogluon.timeseries
3
- Version: 0.7.0b20230329
3
+ Version: 0.7.0b20230331
4
4
  Summary: AutoML for Image, Text, and Tabular Data
5
5
  Home-page: https://github.com/autogluon/autogluon
6
6
  Author: AutoGluon Community
@@ -45,17 +45,10 @@ Requires-Dist: networkx (<3.0,>=2.3)
45
45
  Requires-Dist: statsforecast (<1.5,>=1.4.0)
46
46
  Requires-Dist: tqdm (<5,>=4.38)
47
47
  Requires-Dist: ujson (<6,>=5)
48
- Requires-Dist: autogluon.core[raytune] (==0.7.0b20230329)
49
- Requires-Dist: autogluon.common (==0.7.0b20230329)
50
- Requires-Dist: autogluon.tabular[catboost,lightgbm,xgboost] (==0.7.0b20230329)
48
+ Requires-Dist: autogluon.core[raytune] (==0.7.0b20230331)
49
+ Requires-Dist: autogluon.common (==0.7.0b20230331)
50
+ Requires-Dist: autogluon.tabular[catboost,lightgbm,xgboost] (==0.7.0b20230331)
51
51
  Provides-Extra: all
52
- Requires-Dist: tbats (<2,>=1.1) ; extra == 'all'
53
- Requires-Dist: sktime (<0.16,>=0.14) ; extra == 'all'
54
- Requires-Dist: pmdarima (<1.9,>=1.8.2) ; extra == 'all'
55
- Provides-Extra: sktime
56
- Requires-Dist: sktime (<0.16,>=0.14) ; extra == 'sktime'
57
- Requires-Dist: pmdarima (<1.9,>=1.8.2) ; extra == 'sktime'
58
- Requires-Dist: tbats (<2,>=1.1) ; extra == 'sktime'
59
52
  Provides-Extra: tests
60
53
  Requires-Dist: pytest ; extra == 'tests'
61
54
  Requires-Dist: flake8 (<5,>=4.0) ; extra == 'tests'
@@ -1,16 +1,16 @@
1
- autogluon.timeseries-0.7.0b20230329-py3.8-nspkg.pth,sha256=cQGwpuGPqg1GXscIwt-7PmME1OnSpD-7ixkikJ31WAY,554
2
- autogluon/timeseries/__init__.py,sha256=Gj3vH2ndDbIz30cC_MoP60TEdrkPUjoHqzTGG9k1lhk,1298
1
+ autogluon.timeseries-0.7.0b20230331-py3.8-nspkg.pth,sha256=cQGwpuGPqg1GXscIwt-7PmME1OnSpD-7ixkikJ31WAY,554
2
+ autogluon/timeseries/__init__.py,sha256=w2SX4d7rmGALR8mosOxtVxdBn606SzPBCNv18inWMvw,867
3
3
  autogluon/timeseries/evaluator.py,sha256=AWjqItDZA2tPexQ1e5S3IWTMNL4K-_Bcig6SUzDRkxY,11293
4
4
  autogluon/timeseries/learner.py,sha256=QfkYwKCU0Rp7bhLSGvs7IzVl6AX4_t_NQsQo1JHJtV4,10676
5
5
  autogluon/timeseries/predictor.py,sha256=CPFITx00Tt9-16HxmIzh9yRZ0xr812E3V4aZltZkUDo,41780
6
6
  autogluon/timeseries/splitter.py,sha256=s5S3CeJxcUfZrl7PSXjzubE06bgB8J8uUT8EywSwtYQ,9252
7
- autogluon/timeseries/version.py,sha256=n520bIoM1GEoEMvZTyYf3eyA3vKL3Dq0cg00W0i2xkg,90
7
+ autogluon/timeseries/version.py,sha256=HKsafmNOSycE1XHz3u7_lN_0O5iZR2cZzDotCiuXTBc,90
8
8
  autogluon/timeseries/configs/__init__.py,sha256=BTtHIPCYeGjqgOcvqb8qPD4VNX-ICKOg6wnkew1cPOE,98
9
9
  autogluon/timeseries/configs/presets_configs.py,sha256=chnf3EvCeMP1zUg6aYkz499zrOiMlLul4ETJnNVOslA,799
10
10
  autogluon/timeseries/dataset/__init__.py,sha256=UvnhAN5tjgxXTHoZMQDy64YMDj4Xxa68yY7NP4vAw0o,81
11
11
  autogluon/timeseries/dataset/ts_dataframe.py,sha256=VMvDYe_M0nPuUk4EQVO8ir2ZQm9IIGKdMC74wwPvngk,35226
12
12
  autogluon/timeseries/models/__init__.py,sha256=LFMK5eYZD2t2lvSFX352wUTHxdDi6YLDMAltnjsG2VQ,624
13
- autogluon/timeseries/models/presets.py,sha256=z6gItWywK3PvI51yHhwNoZKn6v0A64xfpJAnlzI2Wmk,9638
13
+ autogluon/timeseries/models/presets.py,sha256=BDgEVKLKpfzZ_-Nc62BjUSgog3ZG4XjgTRMOe8Ii_V0,9269
14
14
  autogluon/timeseries/models/abstract/__init__.py,sha256=DyBTMHj4b4D35aiR83FcCR0_MvPHdqgpmEbdiPoVwcw,168
15
15
  autogluon/timeseries/models/abstract/abstract_timeseries_model.py,sha256=2VpnYOxqvpwkbcDkVkgmjDRHa-bWIfYOG1IMebWEwhM,19622
16
16
  autogluon/timeseries/models/abstract/model_trial.py,sha256=VmpZRRnVSJcX5cAz4mCjVG1-ZlQBmx2tl7Jkp-C-wbM,3653
@@ -27,28 +27,24 @@ autogluon/timeseries/models/gluonts/mx/models.py,sha256=pOUSYD3mDwOoNmxRvzT6GatM
27
27
  autogluon/timeseries/models/gluonts/torch/__init__.py,sha256=YLAjvVe-IBepOntGF0ubbYtZ-4E2vjbzDY0rmn_PZXI,190
28
28
  autogluon/timeseries/models/gluonts/torch/models.py,sha256=ZbzV4BqWnEYb4CMeu7wEESYGJz41XauP5BDZ93-RCn8,14041
29
29
  autogluon/timeseries/models/local/__init__.py,sha256=OJajwc8aaaRuMy4Aw-gpfFkIzEC3qx_UJGYSQp9h-AE,192
30
- autogluon/timeseries/models/local/abstract_local_model.py,sha256=gx5NNsDh3xflCaEnuGXjWGekfT6BJgjL5OadBBia34I,6118
30
+ autogluon/timeseries/models/local/abstract_local_model.py,sha256=GxdSLhYBE9qkX8u3auTbNiarYvfmtL1l2CkuhwfeZ9o,6806
31
31
  autogluon/timeseries/models/local/naive.py,sha256=hTGpQyWjyLRvXtvM42Z3P8dzhio4ZUX1nyEFdcxXCXs,4123
32
- autogluon/timeseries/models/local/statsforecast.py,sha256=zy_mGqCGF4MG5VhV6WqfMHw_A6TwZwFp__d4I1UYdZ4,12171
32
+ autogluon/timeseries/models/local/statsforecast.py,sha256=TpGXCcGgK0Xic-0nz9E80jgOJFLkXMyf3HKsLzvadSM,12125
33
33
  autogluon/timeseries/models/local/statsmodels.py,sha256=VRXNZ0U9DrhfpvheEP-CP_CrHvl9eWDSLvvRQcQ-Ea4,15672
34
- autogluon/timeseries/models/sktime/__init__.py,sha256=x1japG_GbBKE7QNFQV2E6Qzq182eJMRWqHkwZBieTwU,643
35
- autogluon/timeseries/models/sktime/abstract_sktime.py,sha256=DzyK1diw3tewnBoIFIx5e9g15U5fbqKqxIcVX9j-jaU,8255
36
- autogluon/timeseries/models/sktime/models.py,sha256=XRHpJn8dvXtt2tvpF2BLe3HIDxii26dZGTqNJE2LCEQ,16989
37
34
  autogluon/timeseries/trainer/__init__.py,sha256=lxiOT-Gc6BEnr_yWQqra85kEngeM_wtH2SCaRbmC_qE,170
38
35
  autogluon/timeseries/trainer/abstract_trainer.py,sha256=BBetzEtIlDHZbPkvB39y91ai0d4s18biWm8uNjL9aIo,38831
39
36
  autogluon/timeseries/trainer/auto_trainer.py,sha256=Vv2VJENbYz6IszZQE9arDV-QUhkOn1NDImJd6kIhOXM,2684
40
37
  autogluon/timeseries/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
41
38
  autogluon/timeseries/utils/features.py,sha256=QPESzJwMZlsnt_woQ4_I42MOlVT1VcPKk1fTeltPYLU,8270
42
39
  autogluon/timeseries/utils/forecast.py,sha256=06cHkZ4fiIsYpPWF3vAR4x3_AP41rl_w6nv0yMbS5FE,1727
43
- autogluon/timeseries/utils/hashing.py,sha256=tcjTgJ0vA4WV2-WnvF8iW7la5duwCpSUKk37pq_hcBk,954
44
40
  autogluon/timeseries/utils/random.py,sha256=W300Co4eG4txIsnj8pdFFia7DhyVJ5oXWKOEjnGDuVA,344
45
41
  autogluon/timeseries/utils/seasonality.py,sha256=p9mtahWOtDhHUjeGECUJA0VAKeLkZGZbj070dEqMTJQ,652
46
42
  autogluon/timeseries/utils/warning_filters.py,sha256=09a3JgFoVG-bfY92bvr80WfSdLI7CxG1jI546WKPUnw,2330
47
- autogluon.timeseries-0.7.0b20230329.dist-info/LICENSE,sha256=CeipvOyAZxBGUsFoaFqwkx54aPnIKEtm9a5u2uXxEws,10142
48
- autogluon.timeseries-0.7.0b20230329.dist-info/METADATA,sha256=jKdoVsJILsGImtt1cXrPPXSNOL1IAnGVTqzakmFSN6o,12732
49
- autogluon.timeseries-0.7.0b20230329.dist-info/NOTICE,sha256=7nPQuj8Kp-uXsU0S5so3-2dNU5EctS5hDXvvzzehd7E,114
50
- autogluon.timeseries-0.7.0b20230329.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
51
- autogluon.timeseries-0.7.0b20230329.dist-info/namespace_packages.txt,sha256=giERA4R78OkJf2ijn5slgjURlhRPzfLr7waIcGkzYAo,10
52
- autogluon.timeseries-0.7.0b20230329.dist-info/top_level.txt,sha256=giERA4R78OkJf2ijn5slgjURlhRPzfLr7waIcGkzYAo,10
53
- autogluon.timeseries-0.7.0b20230329.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
54
- autogluon.timeseries-0.7.0b20230329.dist-info/RECORD,,
43
+ autogluon.timeseries-0.7.0b20230331.dist-info/LICENSE,sha256=CeipvOyAZxBGUsFoaFqwkx54aPnIKEtm9a5u2uXxEws,10142
44
+ autogluon.timeseries-0.7.0b20230331.dist-info/METADATA,sha256=S3TcWlBhCe-XI21tn4IhGQ7vwkFInzqZJZHR3PXFRQ8,12382
45
+ autogluon.timeseries-0.7.0b20230331.dist-info/NOTICE,sha256=7nPQuj8Kp-uXsU0S5so3-2dNU5EctS5hDXvvzzehd7E,114
46
+ autogluon.timeseries-0.7.0b20230331.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
47
+ autogluon.timeseries-0.7.0b20230331.dist-info/namespace_packages.txt,sha256=giERA4R78OkJf2ijn5slgjURlhRPzfLr7waIcGkzYAo,10
48
+ autogluon.timeseries-0.7.0b20230331.dist-info/top_level.txt,sha256=giERA4R78OkJf2ijn5slgjURlhRPzfLr7waIcGkzYAo,10
49
+ autogluon.timeseries-0.7.0b20230331.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
50
+ autogluon.timeseries-0.7.0b20230331.dist-info/RECORD,,
@@ -1,20 +0,0 @@
1
- import autogluon.timeseries as agts
2
-
3
- if not agts.SKTIME_INSTALLED:
4
- raise ImportError(
5
- "The sktime models in autogluon.timeseries depend on sktime v0.13.1 or greater (below v0.14)."
6
- "Please install a suitable version of sktime in order to use these models, with "
7
- "`pip install 'sktime>=0.13.1,<0.14`."
8
- )
9
-
10
-
11
- from .abstract_sktime import AbstractSktimeModel
12
- from .models import ARIMASktimeModel, AutoARIMASktimeModel, AutoETSSktimeModel, TBATSSktimeModel, ThetaSktimeModel
13
-
14
- __all__ = [
15
- "ARIMASktimeModel",
16
- "AutoARIMASktimeModel",
17
- "AutoETSSktimeModel",
18
- "TBATSSktimeModel",
19
- "ThetaSktimeModel",
20
- ]
@@ -1,185 +0,0 @@
1
- import logging
2
- import re
3
- import warnings
4
- from typing import Any, Dict, List, Optional, Type
5
-
6
- import numpy as np
7
- import pandas as pd
8
- import sktime
9
- from sktime.forecasting.base import BaseForecaster
10
- from statsmodels.tools.sm_exceptions import ConvergenceWarning
11
-
12
- from autogluon.common.utils.log_utils import set_logger_verbosity
13
- from autogluon.timeseries.dataset.ts_dataframe import ITEMID, TIMESTAMP, TimeSeriesDataFrame
14
- from autogluon.timeseries.models.abstract import AbstractTimeSeriesModel
15
- from autogluon.timeseries.utils.forecast import get_forecast_horizon_index_ts_dataframe
16
- from autogluon.timeseries.utils.hashing import hash_ts_dataframe_items
17
- from autogluon.timeseries.utils.seasonality import get_seasonality
18
-
19
- logger = logging.getLogger(__name__)
20
- sktime_logger = logging.getLogger(sktime.__name__)
21
-
22
-
23
- class AbstractSktimeModel(AbstractTimeSeriesModel):
24
- """Abstract class wrapping ``sktime`` estimators for use in autogluon.timeseries.
25
-
26
- Parameters
27
- ----------
28
- path: str
29
- directory to store model artifacts.
30
- freq: str
31
- string representation (compatible with GluonTS frequency strings) for the data provided.
32
- For example, "1D" for daily data, "1H" for hourly data, etc.
33
- prediction_length: int
34
- Number of time steps ahead (length of the forecast horizon) the model will be optimized
35
- to predict. At inference time, this will be the number of time steps the model will
36
- predict.
37
- name: str
38
- Name of the model. Also, name of subdirectory inside path where model will be saved.
39
- eval_metric: str
40
- objective function the model will be scored on, will use mean_wQuantileLoss by default.
41
- hyperparameters:
42
- various hyperparameters that will be used by model (can be search spaces instead of
43
- fixed values). See *Other Parameters* in each inheriting model's documentation for
44
- possible values.
45
- """
46
-
47
- sktime_model_path = "sktime"
48
- sktime_forecaster_class: Type[BaseForecaster] = None
49
- sktime_allowed_init_args: List[str] = []
50
-
51
- def __init__(
52
- self,
53
- freq: Optional[str] = None,
54
- prediction_length: int = 1,
55
- path: Optional[str] = None,
56
- name: Optional[str] = None,
57
- eval_metric: str = None,
58
- hyperparameters: Dict[str, Any] = None,
59
- **kwargs, # noqa
60
- ):
61
- name = name or re.sub(r"Model$", "", self.__class__.__name__)
62
- super().__init__(
63
- path=path,
64
- freq=freq,
65
- prediction_length=prediction_length,
66
- name=name,
67
- eval_metric=eval_metric,
68
- hyperparameters=hyperparameters,
69
- **kwargs,
70
- )
71
- logger.warning(
72
- f"Warning: Model {self.__class__.__name__} has been deprecated in v0.7.\n"
73
- "\tStarting from v0.8, using this model will raise an exception.\n"
74
- "\tConsider instead using other local models such as 'AutoETS', 'AutoARIMA' and 'ARIMA'.",
75
- )
76
- self.sktime_forecaster: Optional[BaseForecaster] = None
77
- self._fit_hash: Optional[pd.Series] = None
78
-
79
- def _get_sktime_forecaster_init_args(self, min_length: int, inferred_period: int = 1):
80
- """Get arguments that will be passed to the sktime forecaster at initialization."""
81
- return self._get_model_params().copy()
82
-
83
- def _get_sktime_forecaster(self, sktime_forecaster_init_args: dict) -> BaseForecaster:
84
- """Create an sktime forecaster object for the model with given args."""
85
- unused_args = [k for k in sktime_forecaster_init_args.keys() if k not in self.sktime_allowed_init_args]
86
- if len(unused_args) > 0:
87
- logger.warning(
88
- f"{self.name} ignores following arguments: {unused_args}. "
89
- f"See `{self.name}.sktime_allowed_init_args` for the list of allowed arguments."
90
- )
91
-
92
- return self.sktime_forecaster_class(
93
- **{k: v for k, v in sktime_forecaster_init_args.items() if k in self.sktime_allowed_init_args} # noqa
94
- )
95
-
96
- def _to_sktime_data_frame(self, data: TimeSeriesDataFrame) -> pd.DataFrame:
97
- """Convert time series data frame's DateTimeIndex to PeriodIndex for use in
98
- sktime, and cast to pandas DataFrame.
99
- """
100
- return pd.DataFrame(
101
- data=data.values,
102
- index=pd.MultiIndex.from_arrays(
103
- [
104
- data.index.get_level_values(0),
105
- data.index.get_level_values(1).to_period(freq=data.freq), # noqa
106
- ]
107
- ),
108
- )
109
-
110
- def _to_time_series_data_frame(self, data: pd.DataFrame, freq: Optional[str] = None) -> TimeSeriesDataFrame:
111
- df = data.copy(deep=False)
112
- df.set_index(
113
- [
114
- df.index.get_level_values(0),
115
- df.index.get_level_values(1).to_timestamp(freq=freq), # noqa
116
- ],
117
- inplace=True,
118
- )
119
- return TimeSeriesDataFrame(df)
120
-
121
- def _fh(self):
122
- return np.arange(1, self.prediction_length + 1)
123
-
124
- def _fit(
125
- self,
126
- train_data: TimeSeriesDataFrame,
127
- time_limit: int = None,
128
- **kwargs,
129
- ) -> None:
130
- verbosity = kwargs.get("verbosity", 2)
131
- set_logger_verbosity(verbosity, logger=logger)
132
- sktime_logger.setLevel(logging.ERROR if verbosity <= 3 else logging.INFO)
133
-
134
- self._check_fit_params()
135
-
136
- min_length = train_data.num_timesteps_per_item().min()
137
- inferred_period = get_seasonality(train_data.freq)
138
- sktime_forecaster_init_args = self._get_sktime_forecaster_init_args(
139
- min_length=min_length, inferred_period=inferred_period
140
- )
141
- self.sktime_forecaster = self._get_sktime_forecaster(sktime_forecaster_init_args)
142
-
143
- with warnings.catch_warnings():
144
- warnings.simplefilter("ignore", category=UserWarning)
145
- warnings.simplefilter("ignore", category=ConvergenceWarning)
146
- warnings.simplefilter("ignore", category=RuntimeWarning)
147
-
148
- self.sktime_forecaster.fit(self._to_sktime_data_frame(train_data[[self.target]]), fh=self._fh())
149
-
150
- self._fit_hash = hash_ts_dataframe_items(train_data)
151
-
152
- def predict(self, data: TimeSeriesDataFrame, quantile_levels: List[float] = None, **kwargs) -> TimeSeriesDataFrame:
153
- self._check_predict_inputs(data, quantile_levels=quantile_levels, **kwargs)
154
-
155
- if not self.sktime_forecaster:
156
- raise ValueError("No sktime forecaster found. Please fit the model first.")
157
-
158
- # sktime trains one local model for each time series (item), so we need to refit if a different set of items is
159
- # given for prediction. We check that train and pred items match using hash based on `timestamp` and `target`
160
- # fields (`item_id` can be different as long as `timestamp` and `target` fields match)
161
- data_hash = hash_ts_dataframe_items(data)
162
- if len(self._fit_hash) != len(data_hash) or (self._fit_hash.values != data_hash.values).any():
163
- logger.warning(
164
- f"Different set of items than those provided during training were provided for "
165
- f"prediction. The model {self.name} will be re-trained on newly provided data"
166
- )
167
- self._fit(data)
168
-
169
- with warnings.catch_warnings():
170
- # Models in statsmodels may run into numerical issues for some datasets - ignore these
171
- warnings.simplefilter("ignore", category=RuntimeWarning)
172
-
173
- mean_predictions = self.sktime_forecaster.predict(fh=self._fh())
174
- quantile_predictions = self.sktime_forecaster.predict_quantiles(
175
- fh=self._fh(), alpha=quantile_levels or self.quantile_levels
176
- )
177
-
178
- mean_predictions.columns = ["mean"]
179
- quantile_predictions.columns = [str(q) for q in quantile_predictions.columns.levels[1]] # noqa
180
-
181
- predictions = pd.concat([mean_predictions, quantile_predictions], axis=1)
182
- predictions_df = self._to_time_series_data_frame(predictions, freq=data.freq)
183
- # Make sure item_id matches `data` (in case trainining and prediction data use different `item_id`s)
184
- predictions_df.index = get_forecast_horizon_index_ts_dataframe(data, self.prediction_length)
185
- return predictions_df
@@ -1,408 +0,0 @@
1
- import logging
2
-
3
- from sktime.forecasting.arima import ARIMA, AutoARIMA
4
- from sktime.forecasting.ets import AutoETS
5
- from sktime.forecasting.tbats import TBATS
6
- from sktime.forecasting.theta import ThetaForecaster
7
-
8
- from . import AbstractSktimeModel
9
-
10
- logger = logging.getLogger(__name__)
11
-
12
-
13
- class ThetaSktimeModel(AbstractSktimeModel):
14
- """Theta model for forecasting.
15
-
16
- Based on `sktime.forecasting.theta.ThetaForecaster <https://www.sktime.org/en/stable/api_reference/auto_generated/sktime.forecasting.theta.ThetaForecaster.html>`_
17
-
18
-
19
- Other Parameters
20
- ----------------
21
- initial_level : float or None, default = None
22
- The alpha value of the simple exponential smoothing, if the value is set then
23
- this will be used, otherwise it will be estimated from the data.
24
- seasonal: bool, default = True
25
- If True, data is seasonally adjusted.
26
- seasonal_period: int or None, default = None
27
- Number of time steps in a complete seasonal cycle for seasonal models. For
28
- example, 4 for quarterly data with an annual cycle, or 7 for daily data with a
29
- weekly cycle.
30
- When set to None, seasonal_period will be inferred from the frequency of the
31
- training data. Can also be specified manually by providing an integer > 1.
32
- fail_if_misconfigured: bool, default = False
33
- If True, the model will raise an exception and fail when given an invalid
34
- configuration (e.g., selected seasonality is incompatible with seasonal_period).
35
- If False, the model will instead raise a warning and try to adjust the
36
- configuration (e.g., turn off seasonality).
37
- Setting this parameter to True is useful during HPO to avoid training multiple
38
- models that all fall back to the same configuration.
39
- """
40
-
41
- sktime_forecaster_class = ThetaForecaster
42
- sktime_allowed_init_args = ["initial_level", "deseasonalize", "sp"]
43
-
44
- def _get_sktime_forecaster_init_args(self, min_length: int, inferred_period: int = 1):
45
- sktime_init_args = self._get_model_params().copy()
46
- fail_if_misconfigured = sktime_init_args.pop("fail_if_misconfigured", False)
47
- # Below code handles both cases when seasonal_period is set to None explicitly & implicitly
48
- seasonal_period = sktime_init_args.pop("seasonal_period", None)
49
- if seasonal_period is None:
50
- seasonal_period = inferred_period
51
- seasonal = sktime_init_args.pop("seasonal", True)
52
- sktime_init_args["deseasonalize"] = seasonal
53
- sktime_init_args["sp"] = seasonal_period
54
-
55
- if seasonal and (min_length < 2 * seasonal_period or seasonal_period <= 1):
56
- error_message = (
57
- f"{self.name} with seasonal = {seasonal} requires training series of length "
58
- f"at least 2 * seasonal_period and seasonal_period > 1 "
59
- f"(received min_length = {min_length} and seasonal_period = {seasonal_period})."
60
- )
61
- if fail_if_misconfigured:
62
- raise ValueError(error_message)
63
- else:
64
- logger.warning(error_message + "\nSetting seasonal to False.")
65
- sktime_init_args["deseasonalize"] = False
66
- sktime_init_args["sp"] = 1
67
- return sktime_init_args
68
-
69
-
70
- class TBATSSktimeModel(AbstractSktimeModel):
71
- """TBATS forecaster with multiple seasonalities.
72
-
73
- This model automatically tries all combinations of hyperparameters (e.g.,
74
- use_box_cox, use_trend, use_arma_errors), and selects the best model
75
-
76
- Based on `sktime.forecasting.tbats.TBATS <https://www.sktime.org/en/stable/api_reference/auto_generated/sktime.forecasting.tbats.TBATS.html>`_
77
-
78
- Caution: The fitting time for this model can be very long, and the saved model can
79
- take up a lot of disk space when applied to large datasets.
80
-
81
-
82
- Other Parameters
83
- ----------------
84
- use_box_cox: bool or None, default = None
85
- Whether to use the Box-Cox transform of the data.
86
- When None, both options are considered and the best one is chosen based on AIC.
87
- use_trend: bool or None, default = None
88
- Whether to use a trend component.
89
- When None, both options are considered and the best one is chosen based on AIC.
90
- use_damped_trend: bool or None, default = None
91
- Whether to damp the trend component.
92
- When None, both options are considered and the best one is chosen based on AIC.
93
- use_arma_erros: bool or None, default = None
94
- Whether to model the residuals with ARMA.
95
- When None, both options are considered and the best one is chosen based on AIC.
96
- seasonal_period: int, float, array or None, default = None
97
- Number of time steps in a complete seasonal cycle for seasonal models. For
98
- example, 4 for quarterly data with an annual cycle, or 7 for daily data with a
99
- weekly cycle.
100
- When set to None, seasonal_period will be inferred from the frequency of the
101
- training data. Setting to 1 disables seasonality.
102
- It's possible to capture multiple trend components by setting seasonal_period
103
- to an array of frequencies.
104
-
105
- Other parameters listed in `sktime_allowed_init_args` can be passed to the underlying
106
- sktime model. See docstring of `sktime.forecasting.tbats.TBATS` for their description.
107
- """
108
-
109
- sktime_forecaster_class = TBATS
110
- sktime_allowed_init_args = [
111
- "use_box_cox",
112
- "box_cox_bounds",
113
- "use_trend",
114
- "use_damped_trend",
115
- "sp",
116
- "use_arma_errors",
117
- "show_warnings",
118
- "n_jobs",
119
- "multiprocessing_start_method",
120
- "context",
121
- ]
122
-
123
- def _get_sktime_forecaster_init_args(self, min_length: int, inferred_period: int = 1):
124
- sktime_init_args = self._get_model_params().copy()
125
- seasonal_period = sktime_init_args.pop("seasonal_period", None)
126
- if seasonal_period is None:
127
- seasonal_period = inferred_period
128
-
129
- if seasonal_period == 1:
130
- sktime_init_args["sp"] = None
131
- else:
132
- sktime_init_args["sp"] = seasonal_period
133
- return sktime_init_args
134
-
135
-
136
- class AutoETSSktimeModel(AbstractSktimeModel):
137
- """AutoETS model from sktime.
138
-
139
- See `AbstractSktimeModel` for common parameters.
140
-
141
- Other Parameters
142
- ----------------
143
- error: str, default = "add"
144
- Error model. Allowed values are "add" and "mul".
145
- trend: str or None, default = None
146
- Trend component model. Allowed values are "add", "mul" and None.
147
- damped_trend: bool, default = False
148
- Whether or not the included trend component is damped.
149
- seasonal: str or None, default = "add"
150
- Seasonality model. Allowed values are "add", "mul" and None.
151
- seasonal_period: int or None, default = None
152
- Number of time steps in a complete seasonal cycle for seasonal models. For
153
- example, 4 for quarterly data with an annual cycle, or 7 for daily data with a
154
- weekly cycle.
155
- When set to None, seasonal_period will be inferred from the frequency of the
156
- training data. Can also be specified manually by providing an integer > 1.
157
- initialization_method: str, default = "estimated"
158
- Method for initializing the model parameters. Allowed values:
159
-
160
- * "estimated" - learn parameters from the data with maximum likelihood
161
- * "heuristic" - select parameters with a heuristic. Faster than "estimated" but
162
- can be less accurate and requires a series with at least 8 elements
163
- fail_if_misconfigured: bool, default = False
164
- If True, the model will raise an exception and fail when given an invalid
165
- configuration (e.g., selected seasonality is incompatible with seasonal_period).
166
- If False, the model will instead raise a warning and try to adjust the
167
- configuration (e.g., turn off seasonality).
168
- Setting this parameter to True is useful during HPO to avoid training multiple
169
- models that all fall back to the same configuration.
170
-
171
- Other parameters listed in `sktime_allowed_init_args` can be passed to the underlying
172
- sktime model. See docstring of `sktime.forecasting.ets.AutoETS` for their description.
173
- """
174
-
175
- sktime_forecaster_class = AutoETS
176
- sktime_allowed_init_args = [
177
- "error",
178
- "trend",
179
- "damped_trend",
180
- "seasonal",
181
- "sp",
182
- "initialization_method",
183
- "initial_level",
184
- "initial_trend",
185
- "initial_seasonal",
186
- "bounds",
187
- "dates",
188
- "freq",
189
- "missing",
190
- "start_params",
191
- "maxiter",
192
- "full_output",
193
- "disp",
194
- "callback",
195
- "return_params",
196
- "auto",
197
- "information_criterion",
198
- "allow_multiplicative_trend",
199
- "restrict",
200
- "additive_only",
201
- "ignore_inf_ic",
202
- "n_jobs",
203
- "random_state",
204
- ]
205
-
206
- def _get_sktime_forecaster_init_args(self, min_length: int, inferred_period: int = 1):
207
- sktime_init_args = self._get_model_params().copy()
208
- fail_if_misconfigured = sktime_init_args.pop("fail_if_misconfigured", False)
209
-
210
- if min_length < 8 and sktime_init_args.get("initialization_method") == "heuristic":
211
- error_message = f"{self.name}: Training series too short for initialization_method='heuristic'."
212
- if fail_if_misconfigured:
213
- raise ValueError(error_message)
214
- else:
215
- logger.warning(error_message + "\nFalling back to initialization_method='estimated'")
216
- sktime_init_args["initialization_method"] = "estimated"
217
-
218
- seasonal = sktime_init_args.pop("seasonal", "add")
219
- if seasonal not in ["add", "mul", None]:
220
- raise ValueError(f"Invalid seasonal {seasonal} for model {self.name} (must be one of 'add', 'mul', None)")
221
-
222
- seasonal_period = sktime_init_args.pop("seasonal_period", None)
223
- if seasonal_period is None:
224
- seasonal_period = inferred_period
225
-
226
- sktime_init_args["seasonal"] = seasonal
227
- sktime_init_args["sp"] = seasonal_period
228
-
229
- # Check if seasonality and seasonal_period are compatible
230
- if seasonal in ["add", "mul"]:
231
- if min_length < 2 * seasonal_period or seasonal_period <= 1:
232
- error_message = (
233
- f"{self.name} with seasonal = {seasonal} requires training series of length "
234
- f"at least 2 * seasonal_period and seasonal_period > 1 "
235
- f"(received min_length = {min_length} and seasonal_period = {seasonal_period})."
236
- )
237
- if fail_if_misconfigured:
238
- raise ValueError(error_message)
239
- else:
240
- logger.warning(error_message + "\nSetting seasonality to None.")
241
- sktime_init_args["seasonal"] = None
242
- sktime_init_args["sp"] = 1
243
- return sktime_init_args
244
-
245
-
246
- class ARIMASktimeModel(AbstractSktimeModel):
247
- """ARIMA model from sktime.
248
-
249
- See `AbstractSktimeModel` for common parameters.
250
-
251
- Other Parameters
252
- ----------------
253
- order: Tuple[int, int, int], default = (1, 0, 0)
254
- The (p, d, q) order of the model for the number of AR parameters, differences,
255
- and MA parameters to use.
256
- seasonal_order: Tuple[int, int, int], default = (1, 0, 1)
257
- The (P, D, Q) parameters of the seasonal ARIMA model. Setting to (0, 0, 0)
258
- disables seasonality.
259
- seasonal_period: int or None, default = None
260
- Number of time steps in a complete seasonal cycle for seasonal models. For
261
- example, 4 for quarterly data with an annual cycle or 7 for daily data with a
262
- weekly cycle.
263
- When set to None, seasonal period will be inferred from the frequency of the
264
- training data. Can also be specified manually by providing an integer > 1.
265
- fail_if_misconfigured: bool, default = False
266
- If True, the model will raise an exception and fail when given an invalid
267
- configuration (e.g., selected seasonal_order is incompatible with seasonal_period).
268
- If False, the model will instead raise a warning and try to adjust the
269
- configuration (e.g., turn off seasonality).
270
- Setting this parameter to True is useful during HPO to avoid training multiple
271
- models that all fall back to the same configuration.
272
-
273
- Other parameters listed in `sktime_allowed_init_args` can be passed to the underlying
274
- sktime model. See docstring of `sktime.forecasting.arima.ARIMA` for their description.
275
- """
276
-
277
- sktime_forecaster_class = ARIMA
278
- sktime_allowed_init_args = [
279
- "order",
280
- "seasonal_order",
281
- "start_params",
282
- "method",
283
- "maxiter",
284
- "suppress_warnings",
285
- "out_of_sample_size",
286
- "scoring",
287
- "scoring_args",
288
- "trend",
289
- "with_intercept",
290
- "time_varying_regression",
291
- "enforce_stationarity",
292
- "enforce_invertibility",
293
- "simple_differencing",
294
- "measurement_error",
295
- "mle_regression",
296
- "hamilton_representation",
297
- "concentrate_scale",
298
- ]
299
-
300
- def _get_sktime_forecaster_init_args(self, min_length: int, inferred_period: int = 1):
301
- sktime_init_args = self._get_model_params().copy()
302
- fail_if_misconfigured = sktime_init_args.pop("fail_if_misconfigured", False)
303
- seasonal_order = sktime_init_args.pop("seasonal_order", (1, 0, 1))
304
- seasonal_period = sktime_init_args.pop("seasonal_period", None)
305
- if seasonal_period is None:
306
- seasonal_period = inferred_period
307
-
308
- seasonal_order_is_valid = len(seasonal_order) == 3 and all(isinstance(p, int) for p in seasonal_order)
309
- if not seasonal_order_is_valid:
310
- raise ValueError(
311
- f"{self.name} can't interpret received seasonal_order {seasonal_order} as a "
312
- "tuple with 3 nonnegative integers (P, D, Q)."
313
- )
314
-
315
- sktime_init_args["seasonal_order"] = tuple(seasonal_order) + (seasonal_period,)
316
-
317
- if seasonal_period <= 1 and any(s > 0 for s in seasonal_order):
318
- error_message = (
319
- f"{self.name} with seasonal_order {seasonal_order} expects "
320
- f"seasonal_period > 1 (received seasonal_period = {seasonal_period})."
321
- )
322
- if fail_if_misconfigured:
323
- raise ValueError(error_message)
324
- else:
325
- logger.warning(error_message + "\nSetting seasonal_order to (0, 0, 0).")
326
- sktime_init_args["seasonal_order"] = (0, 0, 0, 0)
327
-
328
- return sktime_init_args
329
-
330
-
331
- class AutoARIMASktimeModel(AbstractSktimeModel):
332
- """AutoARIMA model from sktime.
333
-
334
- This model automatically selects the (p, d, q) and (P, D, Q) parameters of ARIMA by
335
- fitting multiple models with different configurations and choosing the best one
336
- based on the AIC criterion.
337
-
338
- Other Parameters
339
- ----------------
340
- seasonal_period: int or None, default = None
341
- Number of time steps in a complete seasonal cycle for seasonal models. For
342
- example, 4 for quarterly data with an annual cycle or 7 for daily data with a
343
- weekly cycle.
344
- When set to None, seasonal period will be inferred from the frequency of the
345
- training data. Can also be specified manually by providing an integer > 1.
346
-
347
- Other parameters listed in `sktime_allowed_init_args` can be passed to the underlying
348
- sktime model. See docstring of `sktime.forecasting.arima.AutoARIMA` for their description.
349
- """
350
-
351
- sktime_forecaster_class = AutoARIMA
352
- sktime_allowed_init_args = [
353
- "start_p",
354
- "d",
355
- "start_q",
356
- "max_p",
357
- "max_d",
358
- "max_q",
359
- "start_P",
360
- "D",
361
- "start_Q",
362
- "max_P",
363
- "max_D",
364
- "max_Q",
365
- "max_order",
366
- "sp",
367
- "seasonal",
368
- "stationary",
369
- "information_criterion",
370
- "alpha",
371
- "test",
372
- "seasonal_test",
373
- "stepwise",
374
- "n_jobs",
375
- "start_params",
376
- "trend",
377
- "method",
378
- "maxiter",
379
- "offset_test_args",
380
- "seasonal_test_args",
381
- "suppress_warnings",
382
- "error_action",
383
- "trace",
384
- "random",
385
- "random_state",
386
- "n_fits",
387
- "out_of_sample_size",
388
- "scoring",
389
- "scoring_args",
390
- "with_intercept",
391
- "time_varying_regression",
392
- "enforce_stationarity",
393
- "enforce_invertibility",
394
- "simple_differencing",
395
- "measurement_error",
396
- "mle_regression",
397
- "hamilton_representation",
398
- "concentrate_scale",
399
- ]
400
-
401
- def _get_sktime_forecaster_init_args(self, min_length: int, inferred_period: int = 1):
402
- sktime_init_args = self._get_model_params().copy()
403
- seasonal_period = sktime_init_args.pop("seasonal_period", None)
404
- if seasonal_period is None:
405
- seasonal_period = inferred_period
406
-
407
- sktime_init_args["sp"] = seasonal_period
408
- return sktime_init_args
@@ -1,20 +0,0 @@
1
- import hashlib
2
-
3
- import pandas as pd
4
-
5
- from ..dataset.ts_dataframe import ITEMID, TIMESTAMP, TimeSeriesDataFrame
6
-
7
-
8
- # TODO: Move to autogluon.timeseries.models.statsmodels.helper after we drop the sktime dependency
9
- def hash_ts_dataframe_items(ts_dataframe: TimeSeriesDataFrame) -> pd.Series:
10
- """Hash each time series in the dataset to a 32-character hex string.
11
-
12
- Hash is computed based on the timestamps and values of the time series (item_id is ignored).
13
-
14
- This means that any model that doesn't use static features will make identical predictions for two time series
15
- with the same hash value (assuming no collisions).
16
- """
17
- df_with_timestamp = ts_dataframe.reset_index(level=TIMESTAMP)
18
- hash_per_timestep = pd.util.hash_pandas_object(df_with_timestamp, index=False)
19
- # groupby preserves the order of the timesteps
20
- return hash_per_timestep.groupby(level=ITEMID, sort=False).apply(lambda x: hashlib.md5(x.values).hexdigest())