Exemplo n.º 1
0
    def fit(self, Z, X=None):
        """Fit to data.

        Parameters
        ----------
        Z : pd.Series
        X : pd.DataFrame

        Returns
        -------
        self : an instance of self
        """
        self._is_fitted = False
        z = check_series(Z, enforce_univariate=True)
        self._set_y_index(z)
        sp = check_sp(self.sp)

        # apply seasonal decomposition
        self.seasonal_ = seasonal_decompose(
            z,
            model=self.model,
            period=sp,
            filt=None,
            two_sided=True,
            extrapolate_trend=0,
        ).seasonal.iloc[:sp]

        self._is_fitted = True
        return self
Exemplo n.º 2
0
    def _fit(self, y, X=None, fh=None):
        """Fit to training data.

        Parameters
        ----------
        y : pd.Series
            Target time series to which to fit the forecaster.
        fh : int, list or np.array, optional (default=None)
            The forecasters horizon with the steps ahead to to predict.
        X : pd.DataFrame, optional (default=None)
            Exogenous variables are ignored

        Returns
        -------
        self : returns an instance of self.
        """
        sp = check_sp(self.sp)
        if sp > 1 and not self.deseasonalize:
            warn("`sp` is ignored when `deseasonalise`=False")

        if self.deseasonalize:
            self.deseasonalizer_ = Deseasonalizer(sp=self.sp,
                                                  model="multiplicative")
            y = self.deseasonalizer_.fit_transform(y)

        self.initialization_method = "known" if self.initial_level else "estimated"
        # fit exponential smoothing forecaster
        # find theta lines: Theta lines are just SES + drift
        super(ThetaForecaster, self)._fit(y, fh=fh)
        self.initial_level_ = self._fitted_forecaster.params["smoothing_level"]

        # compute trend
        self.trend_ = self._compute_trend(y)
        return self
Exemplo n.º 3
0
 def __init__(self, sp=1, model="additive"):
     self.sp = check_sp(sp)
     allowed_models = ("additive", "multiplicative")
     if model not in allowed_models:
         raise ValueError(f"`model` must be one of {allowed_models}, "
                          f"but found: {model}")
     self.model = model
     self._y_index = None
     self.seasonal_ = None
     super(Deseasonalizer, self).__init__()
Exemplo n.º 4
0
    def _instantiate_model(self):
        n_jobs = check_n_jobs(self.n_jobs)
        sp = check_sp(self.sp, enforce_list=True)

        return self._ModelClass(
            use_box_cox=self.use_box_cox,
            box_cox_bounds=self.box_cox_bounds,
            use_trend=self.use_trend,
            use_damped_trend=self.use_damped_trend,
            seasonal_periods=sp,
            use_arma_errors=self.use_arma_errors,
            show_warnings=self.show_warnings,
            n_jobs=n_jobs,
            multiprocessing_start_method=self.multiprocessing_start_method,
            context=self.context,
        )
Exemplo n.º 5
0
def autocorrelation_seasonality_test(y, sp):
    """Seasonality test used in M4 competition

    Parameters
    ----------
    sp : int
        Seasonal periodicity

    Returns
    -------
    is_seasonal : bool
        Test result

    References
    ----------
    ..[1]  https://github.com/Mcompetitions/M4-methods/blob/master
    /Benchmarks%20and%20Evaluation.R
    """
    y = check_y(y)
    sp = check_sp(sp)

    y = np.asarray(y)
    n_timepoints = len(y)

    if sp == 1:
        return False

    if n_timepoints < 3 * sp:
        warn(
            "Did not perform seasonality test, as `y`` is too short for the "
            "given `sp`, returned: False"
        )
        return False

    else:
        coefs = acf(y, nlags=sp, fft=False)  # acf coefficients
        coef = coefs[sp]  # coefficient to check

        tcrit = 1.645  # 90% confidence level
        limits = (
            tcrit
            / np.sqrt(n_timepoints)
            * np.sqrt(np.cumsum(np.append(1, 2 * coefs[1:] ** 2)))
        )
        limit = limits[sp - 1]  #  zero-based indexing
        return np.abs(coef) > limit
Exemplo n.º 6
0
    def fit(self, Z, X=None):
        """Fit to data.

        Parameters
        ----------
        y_train : pd.Series

        Returns
        -------
        self : an instance of self
        """

        z = check_series(Z, enforce_univariate=True)
        self._set_y_index(z)
        sp = check_sp(self.sp)

        # set default condition
        if self.seasonality_test is None:
            self.seasonality_test_ = autocorrelation_seasonality_test
        else:
            self.seasonality_test_ = self.seasonality_test

        # check if data meets condition
        self.is_seasonal_ = self._check_condition(z)

        if self.is_seasonal_:
            # if condition is met, apply de-seasonalisation
            self.seasonal_ = seasonal_decompose(
                z,
                model=self.model,
                period=sp,
                filt=None,
                two_sided=True,
                extrapolate_trend=0,
            ).seasonal.iloc[:sp]
        else:
            # otherwise, set idempotent seasonal components
            self.seasonal_ = (
                np.zeros(self.sp) if self.model == "additive" else np.ones(self.sp)
            )

        self._is_fitted = True
        return self
Exemplo n.º 7
0
    def fit(self, Z, X=None):
        """Fit to data.

        Parameters
        ----------
        Z : pd.Series
        X : pd.DataFrame

        Returns
        -------
        self : an instance of self
        """
        self._is_fitted = False
        z = check_series(Z, enforce_univariate=True)
        self._set_y_len(z)
        self._set_y_index(z)
        sp = check_sp(self.sp)

        if sp > 1:
            # apply seasonal decomposition
            _seasonalizer = _STL(
                z.values,
                period=sp,
                seasonal=self.seasonal,
                trend=self.trend,
                low_pass=self.low_pass,
                seasonal_deg=self.seasonal_deg,
                trend_deg=self.trend_deg,
                low_pass_deg=self.low_pass_deg,
                robust=self.robust,
                seasonal_jump=self.seasonal_jump,
                trend_jump=self.trend_jump,
                low_pass_jump=self.low_pass_jump,
            ).fit()
            self.stl_model = _seasonalizer
            self.seasonal_ = self.stl_model.seasonal
        else:
            self.stl_model = None
            self.seasonal_ = np.zeros_like(z.values)

        self.seasonal_ = pd.Series(self.seasonal_, index=Z.index)
        self._is_fitted = True
        return self
Exemplo n.º 8
0
    def fit(self, y_train, **fit_params):
        """Fit to data.

        Parameters
        ----------
        y_train : pd.Series
        fit_params : dict

        Returns
        -------
        self : an instance of self
        """

        y_train = check_y(y_train)
        self._set_oh_index(y_train)
        sp = check_sp(self.sp)

        # set default condition
        if self.seasonality_test is None:
            self.seasonality_test_ = autocorrelation_seasonality_test
        else:
            self.seasonality_test_ = self.seasonality_test

        # check if data meets condition
        self.is_seasonal_ = self._check_condition(y_train)

        if self.is_seasonal_:
            # if condition is met, apply de-seasonalisation
            self.seasonal_ = seasonal_decompose(
                y_train,
                model=self.model,
                period=sp,
                filt=None,
                two_sided=True,
                extrapolate_trend=0).seasonal.iloc[:sp]
        else:
            # otherwise, set idempotent seasonal components
            self.seasonal_ = np.zeros(
                self.sp) if self.model == "additive" else np.ones(self.sp)

        self._is_fitted = True
        return self
Exemplo n.º 9
0
    def fit(self, Z, X=None):
        """Fit to data.

        Parameters
        ----------
        Z : pd.Series
        X : pd.DataFrame

        Returns
        -------
        self : an instance of self
        """
        self._is_fitted = False
        z = check_series(Z, enforce_univariate=True)
        self._Z_index = Z.index
        sp = check_sp(self.sp)

        # The statsmodels.tsa.seasonal.STL can only deal with sp >= 2
        if sp < 2:
            raise ValueError("sp must be positive integer >= 2")
        self._stl = _STL(
            z.values,
            period=sp,
            seasonal=self.seasonal,
            trend=self.trend,
            low_pass=self.low_pass,
            seasonal_deg=self.seasonal_deg,
            trend_deg=self.trend_deg,
            low_pass_deg=self.low_pass_deg,
            robust=self.robust,
            seasonal_jump=self.seasonal_jump,
            trend_jump=self.trend_jump,
            low_pass_jump=self.low_pass_jump,
        ).fit()

        self.seasonal_ = pd.Series(self._stl.seasonal, index=Z.index)
        self.resid_ = pd.Series(self._stl.resid, index=Z.index)
        self.trend_ = pd.Series(self._stl.trend, index=Z.index)

        self._is_fitted = True
        return self
Exemplo n.º 10
0
    def fit(self, y, **fit_params):
        """Fit to data.

        Parameters
        ----------
        y_train : pd.Series
        fit_params : dict

        Returns
        -------
        self : an instance of self
        """

        y = check_y(y)
        self._set_oh_index(y)
        sp = check_sp(self.sp)
        self.seasonal_ = seasonal_decompose(y, model=self.model, period=sp,
                                            filt=None, two_sided=True,
                                            extrapolate_trend=0).seasonal.iloc[
                         :sp]
        self._is_fitted = True
        return self
Exemplo n.º 11
0
    def _fit(self, y, X=None, fh=None):
        """Fit to training data.

        Parameters
        ----------
        y : pd.Series
            Target time series to which to fit the forecaster.
        fh : int, list or np.array, default=None
            The forecasters horizon with the steps ahead to to predict.
        X : pd.DataFrame, default=None
            Exogenous variables are ignored.

        Returns
        -------
        self : returns an instance of self.
        """
        # X_train is ignored

        n_timepoints = y.shape[0]

        if self.strategy in ("last", "mean"):
            # check window length is greater than sp for seasonal mean or seasonal last
            if self.window_length is not None and self.sp != 1:
                if self.window_length < self.sp:
                    raise ValueError(f"The `window_length`: "
                                     f"{self.window_length} is smaller than "
                                     f"`sp`: {self.sp}.")
            self.window_length_ = check_window_length(self.window_length,
                                                      n_timepoints)
            self.sp_ = check_sp(self.sp)

            #  if not given, set default window length
            if self.window_length is None:
                self.window_length_ = len(y)

        elif self.strategy == "drift":
            if self.sp != 1:
                warn(
                    "For the `drift` strategy, the `sp` value will be ignored."
                )
            # window length we need for forecasts is just the
            # length of seasonal periodicity
            self.window_length_ = check_window_length(self.window_length,
                                                      n_timepoints)
            if self.window_length is None:
                self.window_length_ = len(y)
            if self.window_length == 1:
                raise ValueError(f"For the `drift` strategy, "
                                 f"the `window_length`: {self.window_length} "
                                 f"value must be greater than one.")

        else:
            allowed_strategies = ("last", "mean", "drift")
            raise ValueError(f"Unknown strategy: {self.strategy}. Expected "
                             f"one of: {allowed_strategies}.")

        # check window length
        if self.window_length_ > len(self._y):
            param = ("sp" if self.strategy == "last" and self.sp != 1 else
                     "window_length_")
            raise ValueError(
                f"The {param}: {self.window_length_} is larger than "
                f"the training series.")

        return self
Exemplo n.º 12
0
    def fit(self, y_train, fh=None, X_train=None):
        """Fit to training data.

        Parameters
        ----------
        y_train : pd.Series
            Target time series to which to fit the forecaster.
        fh : int, list or np.array, optional (default=None)
            The forecasters horizon with the steps ahead to to predict.
        X_train : pd.DataFrame, optional (default=None)
            Exogenous variables are ignored
        Returns
        -------
        self : returns an instance of self.
        """  # X_train is ignored
        self._set_y_X(y_train, X_train)
        self._set_fh(fh)

        if self.strategy == "last":
            if self.sp == 1:
                if self.window_length is not None:
                    warn("For the `last` strategy, "
                         "the `window_length` value will be ignored if `sp` "
                         "== 1.")
                self.window_length_ = 1

            else:
                self.sp_ = check_sp(self.sp)

                # window length we need for forecasts is just the
                # length of seasonal periodicity
                self.window_length_ = self.sp_

        elif self.strategy == "mean":
            # check window length is greater than sp for seasonal mean
            if self.window_length is not None and self.sp != 1:
                if self.window_length < self.sp:
                    raise ValueError(f"The `window_length`: "
                                     f"{self.window_length} is smaller than "
                                     f"`sp`: {self.sp}.")
            self.window_length_ = check_window_length(self.window_length)
            self.sp_ = check_sp(self.sp)

            #  if not given, set default window length for the mean strategy
            if self.window_length is None:
                self.window_length_ = len(y_train)

        elif self.strategy == "drift":
            if self.sp != 1:
                warn("For the `drift` strategy, "
                     "the `sp` value will be ignored.")
            # window length we need for forecasts is just the
            # length of seasonal periodicity
            self.window_length_ = check_window_length(self.window_length)
            if self.window_length is None:
                self.window_length_ = len(y_train)
            if self.window_length == 1:
                raise ValueError(f"For the `drift` strategy, "
                                 f"the `window_length`: {self.window_length} "
                                 f"value must be greater than one.")

        else:
            allowed_strategies = ("last", "mean", "drift")
            raise ValueError(f"Unknown strategy: {self.strategy}. Expected "
                             f"one of: {allowed_strategies}.")

        # check window length
        if self.window_length_ > len(self._y):
            param = ("sp" if self.strategy == "last" and self.sp != 1 else
                     "window_length_")
            raise ValueError(
                f"The {param}: {self.window_length_} is larger than "
                f"the training series.")

        self._is_fitted = True
        return self