def _compute_pred_errors(self, alpha=DEFAULT_ALPHA): """ Get the prediction errors for the forecast. """ self.check_is_fitted() alpha = check_alpha(alpha) n_timepoints = len(self.oh) self.sigma_ = np.sqrt(self._fitted_forecaster.sse / (n_timepoints - 1)) sem = self.sigma_ * np.sqrt(self._fh * self.smoothing_level_ ** 2 + 1) errors = [] for a in alpha: z = zscore(1 - a) error = z * sem errors.append( pd.Series(error, index=self.fh.absolute(self.cutoff))) # for a single alpha value, unwrap list if len(errors) == 1: return errors[0] # otherwise, return list of errors return errors
def _predict_quantiles(self, fh, X=None, alpha=DEFAULT_ALPHA): """ Compute/return prediction quantiles for a forecast. Must be run *after* the forecaster has been fitted. If alpha is iterable, multiple quantiles will be calculated. Parameters ---------- fh : int, list, np.array or ForecastingHorizon Forecasting horizon, default = y.index (in-sample forecast) X : pd.DataFrame, optional (default=None) Exogenous time series alpha : float or list of float, optional (default=[0.05, 0.95]) A probability or list of, at which quantile forecasts are computed. Returns ------- quantiles : pd.DataFrame Column has multi-index: first level is variable name from y in fit, second level being the values of alpha passed to the function. Row index is fh. Entries are quantile forecasts, for var in col index, at quantile probability in second col index, for the row index. """ self.check_is_fitted() alpha = check_alpha(alpha) # convert alpha to the one needed for predict intervals coverage = [] for a in alpha: if a < 0.5: coverage.append((0.5 - a) * 2) elif a > 0.5: coverage.append((a - 0.5) * 2) else: coverage.append(0) valid_indices = fh.to_absolute(self.cutoff).to_pandas() start, end = valid_indices[[0, -1]] prediction_results = self._fitted_forecaster.get_prediction( start=start, end=end) pred_quantiles = pd.DataFrame() for a, coverage in zip(alpha, coverage): pred_int = prediction_results.pred_int(1 - coverage) pred_int.columns = ["lower", "upper"] if a < 0.5: pred_quantiles[a] = pred_int["lower"].loc[valid_indices] else: pred_quantiles[a] = pred_int["upper"].loc[valid_indices] index = pd.MultiIndex.from_product([["Quantiles"], alpha]) pred_quantiles.columns = index return pred_quantiles
def _predict_quantiles(self, fh, X=None, alpha=DEFAULT_ALPHA): """ Compute/return prediction quantiles for a forecast. Must be run *after* the forecaster has been fitted. If alpha is iterable, multiple quantiles will be calculated. Parameters ---------- fh : int, list, np.array or ForecastingHorizon Forecasting horizon, default = y.index (in-sample forecast) X : pd.DataFrame, optional (default=None) Exogenous time series alpha : float or list of float, optional (default=[0.05, 0.95]) A probability or list of, at which quantile forecasts are computed. Returns ------- quantiles : pd.DataFrame Column has multi-index: first level is variable name from y in fit, second level being the values of alpha passed to the function. Row index is fh. Entries are quantile forecasts, for var in col index, at quantile probability in second col index, for the row index. """ self.check_is_fitted() alpha = check_alpha(alpha) n_timepoints = len(self._y) self.sigma_ = np.sqrt(self._fitted_forecaster.sse / (n_timepoints - 1)) sem = self.sigma_ * np.sqrt( self.fh.to_relative(self.cutoff) * self.initial_level_**2 + 1) errors = [] for a in alpha: z = _zscore(1 - a) error = z * sem errors.append( pd.Series(error, index=self.fh.to_absolute(self.cutoff))) y_pred = super(ThetaForecaster, self).predict(fh, X) pred_quantiles = pd.DataFrame() for a, error in zip(alpha, errors): if a < 0.5: pred_quantiles[a] = y_pred - error else: pred_quantiles[a] = y_pred + error arrays = [len(alpha) * ["Quantiles"], alpha] index = pd.MultiIndex.from_tuples(list(zip(*arrays))) pred_quantiles.columns = index return pred_quantiles
def predict_interval( self, fh=None, X=None, coverage=0.90, ): """Compute/return prediction interval forecasts. If coverage is iterable, multiple intervals will be calculated. State required: Requires state to be "fitted". Accesses in self: Fitted model attributes ending in "_". self.cutoff, self._is_fitted Writes to self: Stores fh to self.fh if fh is passed and has not been passed previously. Parameters ---------- fh : int, list, np.array or ForecastingHorizon Forecasting horizon, default = y.index (in-sample forecast) X : pd.DataFrame, optional (default=None) Exogenous time series coverage : float or list of float, optional (default=0.90) Returns ------- pred_int : pd.DataFrame Column has multi-index: first level is variable name from y in fit, second level being quantile fractions for interval low-high. Quantile fractions are 0.5 - c/2, 0.5 + c/2 for c in coverage. Row index is fh. Entries are quantile forecasts, for var in col index, at quantile probability in second col index, for the row index. """ self.check_is_fitted() # input checks self._set_fh(fh) coverage = check_alpha(coverage) # check and convert X X_inner = self._check_X(X=X) pred_int = self._predict_interval(fh=self.fh, X=X_inner, coverage=coverage) return pred_int
def _convert_new_to_old_pred_int(pred_int_new, alpha): name = pred_int_new.columns.get_level_values(0).unique()[0] alpha = check_alpha(alpha) pred_int_old_format = [ pd.DataFrame({ "lower": pred_int_new[name, a / 2], "upper": pred_int_new[name, 1 - (a / 2)], }) for a in alpha ] # for a single alpha, return single pd.DataFrame if len(alpha) == 1: return pred_int_old_format[0] # otherwise return list of pd.DataFrames return pred_int_old_format
def predict_quantiles(self, fh=None, X=None, alpha=None): """Compute/return quantile forecasts. If alpha is iterable, multiple quantiles will be calculated. State required: Requires state to be "fitted". Accesses in self: Fitted model attributes ending in "_". self.cutoff, self._is_fitted Writes to self: Stores fh to self.fh if fh is passed and has not been passed previously. Parameters ---------- fh : int, list, np.array or ForecastingHorizon Forecasting horizon, default = y.index (in-sample forecast) X : pd.DataFrame, optional (default=None) Exogenous time series alpha : float or list of float, optional (default=[0.05, 0.95]) A probability or list of, at which quantile forecasts are computed. Returns ------- quantiles : pd.DataFrame Column has multi-index: first level is variable name from y in fit, second level being the values of alpha passed to the function. Row index is fh. Entries are quantile forecasts, for var in col index, at quantile probability in second col index, for the row index. """ self.check_is_fitted() # input checks if alpha is None: alpha = [0.05, 0.95] self._set_fh(fh) alpha = check_alpha(alpha) # input check and conversion for X X_inner = self._check_X(X=X) quantiles = self._predict_quantiles(fh=self.fh, X=X_inner, alpha=alpha) return quantiles
def compute_pred_int(self, y_pred, alpha=DEFAULT_ALPHA): """ Compute/return prediction intervals for a forecast. Must be run *after* the forecaster has been fitted. If alpha is iterable, multiple intervals will be calculated. public method including checks & utility dispatches to core logic in _compute_pred_int Parameters ---------- y_pred : pd.Series Point predictions. alpha : float or list, optional (default=0.95) A significance level or list of significance levels. Returns ------- intervals : pd.DataFrame A table of upper and lower bounds for each point prediction in ``y_pred``. If ``alpha`` was iterable, then ``intervals`` will be a list of such tables. """ self.check_is_fitted() alphas = check_alpha(alpha) errors = self._compute_pred_int(alphas) # compute prediction intervals pred_int = [ pd.DataFrame({ "lower": y_pred - error, "upper": y_pred + error }) for error in errors ] # for a single alpha, return single pd.DataFrame if isinstance(alpha, float): return pred_int[0] # otherwise return list of pd.DataFrames return pred_int
def compute_pred_int(self, valid_indices, alpha, **simulate_kwargs): """Compute/return prediction intervals for AutoETS. Must be run *after* the forecaster has been fitted. If alpha is iterable, multiple intervals will be calculated. Parameters ---------- valid_indices : pd.PeriodIndex indices to compute the prediction intervals for alpha : float or list, optional (default=0.95) A significance level or list of significance levels. simulate_kwargs : see statsmodels ETSResults.get_prediction Returns ------- intervals : pd.DataFrame A table of upper and lower bounds for each point prediction in ``y_pred``. If ``alpha`` was iterable, then ``intervals`` will be a list of such tables. """ self.check_is_fitted() alphas = check_alpha(alpha) start, end = valid_indices[[0, -1]] prediction_results = self._fitted_forecaster.get_prediction( start=start, end=end, **simulate_kwargs) pred_ints = [] for alpha_iter in alphas: pred_int = prediction_results.pred_int(alpha_iter) pred_int.columns = ["lower", "upper"] pred_ints.append(pred_int.loc[valid_indices]) if isinstance(alpha, float): pred_ints = pred_ints[0] return pred_ints