def test_conf_int(X_y_linear_trend): HORIZON = 5 X, y = X_y_linear_trend model = TBATS(use_arma_errors=False, use_box_cox=False) model_wrapped = TBATSWrapper(use_arma_errors=False, use_box_cox=False, conf_int=True, conf_int_level=0.95) model = model.fit(y[:-HORIZON]) model_wrapped = model_wrapped.fit(X[:-HORIZON], y[:-HORIZON]) preds_orig, conf_int = model.forecast(steps=HORIZON, confidence_level=0.95) preds = model_wrapped.predict(X[-HORIZON:]) expected_result = (pd.DataFrame( preds_orig, index=X.index[-HORIZON:], columns=["TBATS"]).assign(TBATS_lower=conf_int["lower_bound"]).assign( TBATS_upper=conf_int["upper_bound"])) print("expected_result", expected_result) print("preds", preds) print("preds_orig", preds_orig) assert_frame_equal(preds, expected_result)
class Tbats(base_model.BaseModel): """ Trigonometric seasonality, Box-Cox transformation, ARMA errors, Trend and Seasonal components. """ def _tune(self, y, period, x=None, metric="mse", val_size=None, verbose=False): """ Tune hyperparameters of the model. :param y: pd.Series or 1-D np.array, time series to predict. :param period: Int or Str, the number of observations per cycle: 1 or "annual" for yearly data, 4 or "quarterly" for quarterly data, 7 or "daily" for daily data, 12 or "monthly" for monthly data, 24 or "hourly" for hourly data, 52 or "weekly" for weekly data. First-letter abbreviations of strings work as well ("a", "q", "d", "m", "h" and "w", respectively). Additional reference: https://robjhyndman.com/hyndsight/seasonal-periods/. :param x: not used for TBATS model :param metric: not used for TBATS model; model selection is based on the AIC. :param val_size: Int, the number of most recent observations to use as validation set for tuning. :param verbose: Boolean, True for printing additional info while tuning. :return: None """ self.period = data_utils.period_to_int(period) if type(period) == str else period self.model = TBATS(seasonal_periods=[period], show_warnings=False) self.params["tuned"] = True def fit(self, y, period, x=None, metric="mse", val_size=None, verbose=False): """ Build the model using best-tuned hyperparameter values. :param y: pd.Series or 1-D np.array, time series to predict. :param period: Int or Str, the number of observations per cycle: 1 or "annual" for yearly data, 4 or "quarterly" for quarterly data, 7 or "daily" for daily data, 12 or "monthly" for monthly data, 24 or "hourly" for hourly data, 52 or "weekly" for weekly data. First-letter abbreviations of strings work as well ("a", "q", "d", "m", "h" and "w", respectively). Additional reference: https://robjhyndman.com/hyndsight/seasonal-periods/. :param x: not used for TBATS model :param metric: not used for TBATS model; model selection is based on the AIC. :param val_size: not used for TBATS model; model selection is based on the AIC. :param verbose: Boolean, True for printing additional info while tuning. :return: None """ self.y = y self.name = "TBATS" self.key = "tbats" self._tune(y=y, period=period, x=x, metric=metric, val_size=val_size, verbose=verbose) self.model = self.model.fit(y) def predict(self, horizon, x=None): """ Predict future values of the time series using the fitted model. :param horizon: Int, the number of observations in the future to predict :param x: not used for TBATS model :return: 1-D np.array with predictions """ return self.model.forecast(steps=horizon)
class TBATSFF: """ TBATS wrapper """ def __init__(self): pass def fit(self, ts_init, frcy): self.frcy = frcy self.tbats = TBATS(seasonal_periods=[self.frcy, 7 * self.frcy], use_arma_errors=False).fit(ts_init) return self def predict(self, h): y_hat = self.tbats.forecast(steps=h) return y_hat