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_oh(y_train) self._set_fh(fh) if self.strategy in ("last", "seasonal_last"): if self.window_length is not None: warn("For the `last` and `seasonal_last` strategy, " "the `window_length_` value will be ignored.") if self.strategy in ("last", "mean"): if self.sp is not None: warn("For the `last` and `mean` strategy, " "the `sp` value will be ignored.") if self.strategy == "last": self.window_length_ = 1 if self.strategy == "seasonal_last": if self.sp is None: raise NotImplementedError( "Automatic estimation of the seasonal periodicity `sp` " "from the data is not implemented yet; " "please specify the `sp` value.") self.sp_ = check_sp(self.sp) # window length we need for forecasts is just the # length of seasonal periodicity self.window_length_ = self.sp_ if self.strategy == "mean": self.window_length_ = check_window_length(self.window_length) # if not given, set default window length for the mean strategy if self.strategy == "mean" and self.window_length is None: self.window_length_ = len(y_train) # check window length if self.window_length_ > len(self.oh): param = "sp" if self.strategy == "seasonal_last" else \ "window_length_" raise ValueError( f"The {param}: {self.window_length_} is larger than " f"the training series.") self._is_fitted = True return self
def _split_windows(self, y): window_length = check_window_length(self.window_length) fh = self._check_fh() end = self._get_end(y) - 1 start = 0 if window_length is None else end - window_length training_window = np.arange(start, end) test_window = end + fh - 1 yield training_window, test_window
def _split_windows(self, y): step_length = check_step_length(self.step_length) window_length = check_window_length(self.window_length) fh = self._check_fh() end = self._get_end(y) start = self._get_start() for split_point in range(start, end, step_length): training_window = np.arange(split_point - window_length, split_point) test_window = split_point + fh - 1 yield training_window, test_window
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. """ self._set_y_X(y_train, X_train) if X_train is not None: raise NotImplementedError() self._set_fh(fh) if len(self.fh.to_in_sample(self.cutoff)) > 0: raise NotImplementedError("In-sample predictions are" " not implemented") self.step_length_ = check_step_length(self.step_length) self.window_length_ = check_window_length(self.window_length) # for the direct reduction strategy, a separate forecaster is fitted # for each step ahead of the forecasting horizon self._cv = SlidingWindowSplitter( fh=self.fh.to_relative(self.cutoff), window_length=self.window_length_, step_length=self.step_length_, start_with_window=True, ) # transform data using rolling window split X_train, Y_train = self._transform(y_train, X_train) # iterate over forecasting horizon self.regressors_ = [] for i in range(len(self.fh)): y_train = Y_train[:, i] regressor = clone(self.regressor) regressor.fit(X_train, y_train) self.regressors_.append(regressor) self._is_fitted = True return self
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. """ # input checks if X_train is not None: raise NotImplementedError() # set values self._set_y_X(y_train, X_train) self._set_fh(fh) # Set this and then call the super method, that should be enought I think ..... self._nbr_dependent = y_train.shape[1] self.step_length_ = check_step_length(self.step_length) self.window_length_ = check_window_length(self.window_length) # set up cv iterator, for recursive strategy, a single estimator # is fit for a one-step-ahead forecasting horizon and then called # iteratively to predict multiple steps ahead self._cv = SlidingWindowSplitter( fh=1, window_length=self.window_length_, step_length=self.step_length_, start_with_window=True, ) # transform data into tabular form X_train_tab, y_train_tab = self._transform(y_train, X_train) # fit base regressor regressor = clone(self.regressor) regressor.fit(X_train_tab, y_train_tab) self.regressor_ = regressor self._is_fitted = True return self
def _split_windows(self, y): # cutoffs cutoffs = check_cutoffs(self.cutoffs) if not np.max(cutoffs) < len(y): raise ValueError("`cutoffs` are out-of-bounds for given `y`.") fh = self._check_fh() if np.max(cutoffs) + np.max(fh) > len(y): raise ValueError( "`fh` is out-of-bounds for given `cutoffs` and `y`.") window_length = check_window_length(self.window_length) for cutoff in cutoffs: training_window = np.arange(cutoff - window_length, cutoff) + 1 test_window = cutoff + fh yield training_window, test_window
def _get_end(self, y): """Helper function to compute the end of the last window""" n_timepoints = len(y) fh = check_fh(self.fh) window_length = check_window_length(self.window_length) # end point is end of last window is_in_sample = np.all(fh <= 0) if is_in_sample: end = n_timepoints + 1 else: fh_max = fh[-1] end = n_timepoints - fh_max + 1 # non-inclusive end indexing # check if computed values are feasible with the provided index if window_length is not None and window_length + fh_max > n_timepoints: raise ValueError( "The window length and forecasting horizon are " "incompatible with the length of `y`") return end
def split_initial(self, y): """Split initial window This is useful during forecasting model selection where we want to fit the forecaster on some part of the data first before doing temporal cross-validation Parameters ---------- y : pd.Series Returns ------- intial_training_window : np.array initial_test_window : np.array """ if self.initial_window is None: raise ValueError( "Please specify initial window, found: `initial_window`=None") initial = check_window_length(self.initial_window) initial_training_window = np.arange(initial) initial_test_window = np.arange(initial, len(y)) return initial_training_window, initial_test_window
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
def _get_start(self): window_length = check_window_length(self.window_length) if self.start_with_window: return window_length else: return 0