Source code for autogluon.timeseries.models.sktime.models
import logging
from sktime.forecasting.arima import ARIMA, AutoARIMA
from sktime.forecasting.ets import AutoETS
from sktime.forecasting.tbats import TBATS
from sktime.forecasting.theta import ThetaForecaster
from . import AbstractSktimeModel
logger = logging.getLogger(__name__)
class SktimeThetaModel(AbstractSktimeModel):
"""Theta model for forecasting.
Based on `sktime.forecasting.theta.ThetaForecaster <https://www.sktime.org/en/stable/api_reference/auto_generated/sktime.forecasting.theta.ThetaForecaster.html>`_
Other Parameters
----------------
initial_level : float or None, default = None
The alpha value of the simple exponential smoothing, if the value is set then
this will be used, otherwise it will be estimated from the data.
seasonal: bool, default = True
If True, data is seasonally adjusted.
seasonal_period: int or None, default = None
Number of time steps in a complete seasonal cycle for seasonal models. For
example, 4 for quarterly data with an annual cycle, or 7 for daily data with a
weekly cycle.
When set to None, seasonal_period will be inferred from the frequency of the
training data. Can also be specified manually by providing an integer > 1.
fail_if_misconfigured: bool, default = False
If True, the model will raise an exception and fail when given an invalid
configuration (e.g., selected seasonality is incompatible with seasonal_period).
If False, the model will instead raise a warning and try to adjust the
configuration (e.g., turn off seasonality).
Setting this parameter to True is useful during HPO to avoid training multiple
models that all fall back to the same configuration.
"""
sktime_forecaster_class = ThetaForecaster
sktime_allowed_init_args = ["initial_level", "deseasonalize", "sp"]
def _get_sktime_forecaster_init_args(self, min_length: int, inferred_period: int = 1):
sktime_init_args = self._get_model_params().copy()
fail_if_misconfigured = sktime_init_args.pop("fail_if_misconfigured", False)
# Below code handles both cases when seasonal_period is set to None explicitly & implicitly
seasonal_period = sktime_init_args.pop("seasonal_period", None)
if seasonal_period is None:
seasonal_period = inferred_period
seasonal = sktime_init_args.pop("seasonal", True)
sktime_init_args["deseasonalize"] = seasonal
sktime_init_args["sp"] = seasonal_period
if seasonal and (min_length < 2 * seasonal_period or seasonal_period <= 1):
error_message = (
f"{self.name} with seasonal = {seasonal} requires training series of length "
f"at least 2 * seasonal_period and seasonal_period > 1 "
f"(received min_length = {min_length} and seasonal_period = {seasonal_period})."
)
if fail_if_misconfigured:
raise ValueError(error_message)
else:
logger.warning(error_message + "\nSetting seasonal to False.")
sktime_init_args["deseasonalize"] = False
sktime_init_args["sp"] = 1
return sktime_init_args
[docs]class SktimeTBATSModel(AbstractSktimeModel):
"""TBATS forecaster with multiple seasonalities.
This model automatically tries all combinations of hyperparameters (e.g.,
use_box_cox, use_trend, use_arma_errors), and selects the best model
Based on `sktime.forecasting.tbats.TBATS <https://www.sktime.org/en/stable/api_reference/auto_generated/sktime.forecasting.tbats.TBATS.html>`_
Caution: The fitting time for this model can be very long, and the saved model can
take up a lot of disk space when applied to large datasets.
Other Parameters
----------------
use_box_cox: bool or None, default = None
Whether to use the Box-Cox transform of the data.
When None, both options are considered and the best one is chosen based on AIC.
use_trend: bool or None, default = None
Whether to use a trend component.
When None, both options are considered and the best one is chosen based on AIC.
use_damped_trend: bool or None, default = None
Whether to damp the trend component.
When None, both options are considered and the best one is chosen based on AIC.
use_arma_erros: bool or None, default = None
Whether to model the residuals with ARMA.
When None, both options are considered and the best one is chosen based on AIC.
seasonal_period: int, float, array or None, default = None
Number of time steps in a complete seasonal cycle for seasonal models. For
example, 4 for quarterly data with an annual cycle, or 7 for daily data with a
weekly cycle.
When set to None, seasonal_period will be inferred from the frequency of the
training data. Setting to 1 disables seasonality.
It's possible to capture multiple trend components by setting seasonal_period
to an array of frequencies.
Other parameters listed in `sktime_allowed_init_args` can be passed to the underlying
sktime model. See docstring of `sktime.forecasting.tbats.TBATS` for their description.
"""
sktime_forecaster_class = TBATS
sktime_allowed_init_args = [
"use_box_cox",
"box_cox_bounds",
"use_trend",
"use_damped_trend",
"sp",
"use_arma_errors",
"show_warnings",
"n_jobs",
"multiprocessing_start_method",
"context",
]
def _get_sktime_forecaster_init_args(self, min_length: int, inferred_period: int = 1):
sktime_init_args = self._get_model_params().copy()
seasonal_period = sktime_init_args.pop("seasonal_period", None)
if seasonal_period is None:
seasonal_period = inferred_period
if seasonal_period == 1:
sktime_init_args["sp"] = None
else:
sktime_init_args["sp"] = seasonal_period
return sktime_init_args
class SktimeAutoETSModel(AbstractSktimeModel):
"""AutoETS model from sktime.
See `AbstractSktimeModel` for common parameters.
Other Parameters
----------------
error: str, default = "add"
Error model. Allowed values are "add" and "mul".
trend: str or None, default = None
Trend component model. Allowed values are "add", "mul" and None.
damped_trend: bool, default = False
Whether or not the included trend component is damped.
seasonal: str or None, default = "add"
Seasonality model. Allowed values are "add", "mul" and None.
seasonal_period: int or None, default = None
Number of time steps in a complete seasonal cycle for seasonal models. For
example, 4 for quarterly data with an annual cycle, or 7 for daily data with a
weekly cycle.
When set to None, seasonal_period will be inferred from the frequency of the
training data. Can also be specified manually by providing an integer > 1.
initialization_method: str, default = "estimated"
Method for initializing the model parameters. Allowed values:
* "estimated" - learn parameters from the data with maximum likelihood
* "heuristic" - select parameters with a heuristic. Faster than "estimated" but
can be less accurate and requires a series with at least 8 elements
fail_if_misconfigured: bool, default = False
If True, the model will raise an exception and fail when given an invalid
configuration (e.g., selected seasonality is incompatible with seasonal_period).
If False, the model will instead raise a warning and try to adjust the
configuration (e.g., turn off seasonality).
Setting this parameter to True is useful during HPO to avoid training multiple
models that all fall back to the same configuration.
Other parameters listed in `sktime_allowed_init_args` can be passed to the underlying
sktime model. See docstring of `sktime.forecasting.ets.AutoETS` for their description.
"""
sktime_forecaster_class = AutoETS
sktime_allowed_init_args = [
"error",
"trend",
"damped_trend",
"seasonal",
"sp",
"initialization_method",
"initial_level",
"initial_trend",
"initial_seasonal",
"bounds",
"dates",
"freq",
"missing",
"start_params",
"maxiter",
"full_output",
"disp",
"callback",
"return_params",
"auto",
"information_criterion",
"allow_multiplicative_trend",
"restrict",
"additive_only",
"ignore_inf_ic",
"n_jobs",
"random_state",
]
def _get_sktime_forecaster_init_args(self, min_length: int, inferred_period: int = 1):
sktime_init_args = self._get_model_params().copy()
fail_if_misconfigured = sktime_init_args.pop("fail_if_misconfigured", False)
if min_length < 8 and sktime_init_args.get("initialization_method") == "heuristic":
error_message = f"{self.name}: Training series too short for initialization_method='heuristic'."
if fail_if_misconfigured:
raise ValueError(error_message)
else:
logger.warning(error_message + "\nFalling back to initialization_method='estimated'")
sktime_init_args["initialization_method"] = "estimated"
seasonal = sktime_init_args.pop("seasonal", "add")
if seasonal not in ["add", "mul", None]:
raise ValueError(f"Invalid seasonal {seasonal} for model {self.name} (must be one of 'add', 'mul', None)")
seasonal_period = sktime_init_args.pop("seasonal_period", None)
if seasonal_period is None:
seasonal_period = inferred_period
sktime_init_args["seasonal"] = seasonal
sktime_init_args["sp"] = seasonal_period
# Check if seasonality and seasonal_period are compatible
if seasonal in ["add", "mul"]:
if min_length < 2 * seasonal_period or seasonal_period <= 1:
error_message = (
f"{self.name} with seasonal = {seasonal} requires training series of length "
f"at least 2 * seasonal_period and seasonal_period > 1 "
f"(received min_length = {min_length} and seasonal_period = {seasonal_period})."
)
if fail_if_misconfigured:
raise ValueError(error_message)
else:
logger.warning(error_message + "\nSetting seasonality to None.")
sktime_init_args["seasonal"] = None
sktime_init_args["sp"] = 1
return sktime_init_args
class SktimeARIMAModel(AbstractSktimeModel):
"""ARIMA model from sktime.
See `AbstractSktimeModel` for common parameters.
Other Parameters
----------------
order: Tuple[int, int, int], default = (1, 0, 0)
The (p, d, q) order of the model for the number of AR parameters, differences,
and MA parameters to use.
seasonal_order: Tuple[int, int, int], default = (1, 0, 1)
The (P, D, Q) parameters of the seasonal ARIMA model. Setting to (0, 0, 0)
disables seasonality.
seasonal_period: int or None, default = None
Number of time steps in a complete seasonal cycle for seasonal models. For
example, 4 for quarterly data with an annual cycle or 7 for daily data with a
weekly cycle.
When set to None, seasonal period will be inferred from the frequency of the
training data. Can also be specified manually by providing an integer > 1.
fail_if_misconfigured: bool, default = False
If True, the model will raise an exception and fail when given an invalid
configuration (e.g., selected seasonal_order is incompatible with seasonal_period).
If False, the model will instead raise a warning and try to adjust the
configuration (e.g., turn off seasonality).
Setting this parameter to True is useful during HPO to avoid training multiple
models that all fall back to the same configuration.
Other parameters listed in `sktime_allowed_init_args` can be passed to the underlying
sktime model. See docstring of `sktime.forecasting.arima.ARIMA` for their description.
"""
sktime_forecaster_class = ARIMA
sktime_allowed_init_args = [
"order",
"seasonal_order",
"start_params",
"method",
"maxiter",
"suppress_warnings",
"out_of_sample_size",
"scoring",
"scoring_args",
"trend",
"with_intercept",
"time_varying_regression",
"enforce_stationarity",
"enforce_invertibility",
"simple_differencing",
"measurement_error",
"mle_regression",
"hamilton_representation",
"concentrate_scale",
]
def _get_sktime_forecaster_init_args(self, min_length: int, inferred_period: int = 1):
sktime_init_args = self._get_model_params().copy()
fail_if_misconfigured = sktime_init_args.pop("fail_if_misconfigured", False)
seasonal_order = sktime_init_args.pop("seasonal_order", (1, 0, 1))
seasonal_period = sktime_init_args.pop("seasonal_period", None)
if seasonal_period is None:
seasonal_period = inferred_period
seasonal_order_is_valid = len(seasonal_order) == 3 and all(isinstance(p, int) for p in seasonal_order)
if not seasonal_order_is_valid:
raise ValueError(
f"{self.name} can't interpret received seasonal_order {seasonal_order} as a "
"tuple with 3 nonnegative integers (P, D, Q)."
)
sktime_init_args["seasonal_order"] = tuple(seasonal_order) + (seasonal_period,)
if seasonal_period <= 1 and any(s > 0 for s in seasonal_order):
error_message = (
f"{self.name} with seasonal_order {seasonal_order} expects "
f"seasonal_period > 1 (received seasonal_period = {seasonal_period})."
)
if fail_if_misconfigured:
raise ValueError(error_message)
else:
logger.warning(error_message + "\nSetting seasonal_order to (0, 0, 0).")
sktime_init_args["seasonal_order"] = (0, 0, 0, 0)
return sktime_init_args
class SktimeAutoARIMAModel(AbstractSktimeModel):
"""AutoARIMA model from sktime.
This model automatically selects the (p, d, q) and (P, D, Q) parameters of ARIMA by
fitting multiple models with different configurations and choosing the best one
based on the AIC criterion.
Other Parameters
----------------
seasonal_period: int or None, default = None
Number of time steps in a complete seasonal cycle for seasonal models. For
example, 4 for quarterly data with an annual cycle or 7 for daily data with a
weekly cycle.
When set to None, seasonal period will be inferred from the frequency of the
training data. Can also be specified manually by providing an integer > 1.
Other parameters listed in `sktime_allowed_init_args` can be passed to the underlying
sktime model. See docstring of `sktime.forecasting.arima.AutoARIMA` for their description.
"""
sktime_forecaster_class = AutoARIMA
sktime_allowed_init_args = [
"start_p",
"d",
"start_q",
"max_p",
"max_d",
"max_q",
"start_P",
"D",
"start_Q",
"max_P",
"max_D",
"max_Q",
"max_order",
"sp",
"seasonal",
"stationary",
"information_criterion",
"alpha",
"test",
"seasonal_test",
"stepwise",
"n_jobs",
"start_params",
"trend",
"method",
"maxiter",
"offset_test_args",
"seasonal_test_args",
"suppress_warnings",
"error_action",
"trace",
"random",
"random_state",
"n_fits",
"out_of_sample_size",
"scoring",
"scoring_args",
"with_intercept",
"time_varying_regression",
"enforce_stationarity",
"enforce_invertibility",
"simple_differencing",
"measurement_error",
"mle_regression",
"hamilton_representation",
"concentrate_scale",
]
def _get_sktime_forecaster_init_args(self, min_length: int, inferred_period: int = 1):
sktime_init_args = self._get_model_params().copy()
seasonal_period = sktime_init_args.pop("seasonal_period", None)
if seasonal_period is None:
seasonal_period = inferred_period
sktime_init_args["sp"] = seasonal_period
return sktime_init_args