MSTL
Season-Trend decomposition using LOESS for multiple seasonalities.
Direct interface for statsmodels.tsa.seasonal.MSTL for transform, with sktime native extensions to allow use in forecasting pipelines.
MSTL can be used to perform deseasonalization or decomposition:
fit stores the decomposed values in self.trend_, self.seasonal_, and self.resid_.
If return_components=False, then transform returns a pd.Series of the deseasonalized values, i.e., trend plus residual component. The individual seasonal and residual components can be found in self.trend_ and self.resid_.
If return_components=True, then transform returns a full components decomposition, in a DataFrame with cols (for each input column), in this order:
“trend” - the trend component
“resid” - the residuals after de-trending, de-seasonalizing
“seasonal” - a single sum-of-seasonalities component, if
periodsisNone.“seasonal_<period>” - the seasonal component(s), where <period> is an integer indicating the periodicity, one such component per element in
periods, ifperiodsis an array-like of integers.
MSTL performs inverse_transform by reconstituting the signal from its components, and can be used for pipelining in a TransformedTargetForecaster, see examples below.
if
periodsare provided, the transformation will deseasonalize, and reseasonalize after forecast.if
periodsare not provided, andreturn_components=False, the forecast will be a pure trend forecast, using sum of trend and residual components.if
return_components=True, the forecaster has access to all components, and can apply different forecasters to different components.
See the examples below for usage.
For automated detection of seasonalities using a custom seasonality detection algorithm, pipeline MSTL with the respective estimator, e.g., SeasonalityACF.
Schnellstart
from sktime.transformations.detrend.mstl import MSTL
estimator = MSTL(*, periods: int | Sequence [int ] | None=None, windows: int | Sequence [int ] | None=None, lmbda: float | str | None=None, iterate: int | None=2, stl_kwargs: dict [str, int | bool | None ] | None=None, return_components: bool=False)Parameter(7)
- endogarray_like
- Data to be decomposed. Must be squeezable to 1-d.
- periods{int, array_like, None}, optional
- Periodicity of the seasonal components. If None and endog is a pandas Series or DataFrame, attempts to determine from endog. If endog is a ndarray, periods must be provided.
- windows{int, array_like, None}, optional
- Length of the seasonal smoothers for each corresponding period. Must be an odd integer, and should normally be >= 7 (default). If None then default values determined using 7 + 4 * np.arange(1, n + 1, 1) where n is number of seasonal components.
- lmbda{float, str, None}, optional
The lambda parameter for the Box-Cox transform to be applied to endog prior to decomposition. If None, no transform is applied. If
auto, a value will be estimated that maximizes the log-likelihood function.- iterateint, optional
- Number of iterations to use to refine the seasonal component.
- stl_kwargsdict, optional
- Arguments to pass to STL.
- return_componentsbool, default=False
if False, will return only the MSTL transformed series, same as trend plus residual component. The resulting series has the same number of columns as the input.
- if True, will return all components of the decomposition,
a multivariate series with DataFrame cols (for each input column):
“trend” - the trend component
“resid” - the residuals after de-trending, de-seasonalizing
“seasonal” - a single sum-of-seasonalities component, if
periodsisNone. * “seasonal_<period>” - the seasonal component(s),where <period> is an integer indicating the periodicity, one such component per element in
periodsAll components together sum up to the original series, in-sample.
Beispiele
Simple use case: decompose a time series into trend, seasonal, residual components
>>> import matplotlib.pyplot as plt # doctest: +SKIP
>>> from sktime.datasets import load_airline
>>> from sktime.transformations.detrend import MSTL
>>> X = load_airline()
>>> X.index = X.index.to_timestamp()
>>> mstl = MSTL(return_components=True)
>>> mstl.fit(X) MSTL(…)
>>> res = mstl.transform(X)
>>> res.plot() # doctest: +SKIP
>>> plt.tight_layout() # doctest: +SKIP
>>> plt.show() # doctest: +SKIP MSTL can be pipelined with a forecaster for multiple deseasonalized forecasts. The following example uses a simple trend forecaster, applied to a series deseasonalized with MSTL at periods 2 and 12. After the trend forecast, the seasonal components are added back to the forecast automatically.
>>> from sktime.datasets import load_airline
>>> from sktime.transformations.detrend import MSTL
>>> from sktime.forecasting.trend import TrendForecaster
>>>
>>> mstl_trafo = MSTL(periods=[2, 12])
>>> mstl_deseason_fcst = mstl_trafo * TrendForecaster()
>>> y = load_airline()
>>> mstl_deseason_fcst.fit(y, fh=[1, 2, 3]) TransformedTargetForecaster(…)
>>> y_pred = mstl_deseason_fcst.predict() MSTL can also be used to make forecasts using the full component decomposition. For this, set return_components=True when pipelining. The forecaster in the pipeline will then be given a multivariate series with the components as columns, i.e., “trend”, “resid”, “seasonal_2”, “seasonal_12”. To apply different forecasters to different components, use a ColumnEnsembleForecaster; to apply the same forecaster to all components, simply pipeline with the forecaster. The following example uses a TrendForecaster for the trend, a seasonal naive forecaster for the seasonal components, with different seasonalities, and a naive forecaster for the residuals.
>>> from sktime.datasets import load_airline
>>> from sktime.transformations.detrend import MSTL
>>> from sktime.forecasting.compose import ColumnEnsembleForecaster
>>> from sktime.forecasting.naive import NaiveForecaster
>>> from sktime.forecasting.trend import TrendForecaster
>>>
>>> mstl_trafo_comp = MSTL(periods=[2, 12], return_components=True)
>>> mstl_component_fcst = mstl_trafo_comp * ColumnEnsembleForecaster(… [… (“trend”, TrendForecaster(), “trend”), … (“sp2”, NaiveForecaster(strategy=”last”, sp=2), “seasonal_2”), … (“sp12”, NaiveForecaster(strategy=”last”, sp=12), “seasonal_12”), … (“residual”, NaiveForecaster(strategy=”last”), “resid”), … ] …)
>>> y = load_airline()
>>> mstl_component_fcst.fit(y, fh=[1, 2, 3]) TransformedTargetForecaster(…)
>>> y_pred = mstl_component_fcst.predict()