class_docstr: A base class for forecast estimators that fit using
  `~greykite.algo.forecast.silverkite.forecast_silverkite.SilverkiteForecast.forecast`.
  
  Notes
  -----
  Allows estimators that fit using
  `~greykite.algo.forecast.silverkite.forecast_silverkite.SilverkiteForecast.forecast`
  to share the same functions for input data validation,
  fit postprocessing, predict, summary, plot_components, etc.
  
  Subclasses should:
  
      - Implement their own ``__init__`` that uses a superset of the parameters here.
      - Implement their own ``fit``, with this sequence of steps:
  
          - calls ``super().fit``
          - calls ``SilverkiteForecast.forecast`` or ``SimpleSilverkiteForecast.forecast_simple`` and stores the result in ``self.model_dict``
          - calls ``super().finish_fit``
  
  Uses ``coverage`` to set prediction band width. Even though
  coverage is not needed by ``forecast_silverkite``, it is included
  in every ``BaseForecastEstimator`` to be used universally for
  forecast evaluation.
  
  Therefore, ``uncertainty_dict`` must be consistent with ``coverage``
  if provided as a dictionary. If ``uncertainty_dict`` is None or
  "auto", an appropriate default value is set, according to ``coverage``.
  
  Parameters
  ----------
  score_func : callable, optional, default mean_squared_error
      See `~greykite.sklearn.estimator.base_forecast_estimator.BaseForecastEstimator`.
  coverage : `float` between [0.0, 1.0] or None, optional
      See `~greykite.sklearn.estimator.base_forecast_estimator.BaseForecastEstimator`.
  null_model_params : `dict`, optional
      Dictionary with arguments to define DummyRegressor null model, default is `None`.
      See `~greykite.sklearn.estimator.base_forecast_estimator.BaseForecastEstimator`.
  uncertainty_dict : `dict` or `str` or None, optional
      How to fit the uncertainty model.
      See `~greykite.algo.forecast.silverkite.forecast_silverkite.SilverkiteForecast.forecast`.
      Note that this is allowed to be "auto". If None or "auto", will be set to
      a default value by ``coverage`` before calling ``forecast_silverkite``.
  
  Attributes
  ----------
  silverkite : Class or a derived class of `~greykite.algo.forecast.silverkite.forecast_silverkite.SilverkiteForecast`
      The silverkite algorithm instance used for forecasting
  model_dict : `dict` or None
      A dict with fitted model and its attributes.
      The output of `~greykite.algo.forecast.silverkite.forecast_silverkite.SilverkiteForecast.forecast`.
  pred_cols : `list` [`str`] or None
      Names of the features used in the model.
  feature_cols : `list` [`str`] or None
      Column names of the patsy design matrix built by
      `~greykite.algo.common.ml_models.design_mat_from_formula`.
  df : `pandas.DataFrame` or None
      The training data used to fit the model.
  coef_ : `pandas.DataFrame` or None
      Estimated coefficient matrix for the model.
      Not available for ``random forest`` and ``gradient boosting`` methods and
      set to the default value `None`.
  _pred_category : `dict` or None
      A dictionary with keys being the predictor category and
      values being the predictors belonging to the category.
      For details, see
      `~greykite.sklearn.estimator.base_silverkite_estimator.BaseSilverkiteEstimator.pred_category`.
  extra_pred_cols : `list` or None
      User provided extra predictor names, for details, see
      `~greykite.sklearn.estimator.simple_silverkite_estimator.SimpleSilverkiteEstimator`
      or
      `~greykite.sklearn.estimator.silverkite_estimator.SilverkiteEstimator`.
  past_df : `pandas.DataFrame` or None
      The extra past data before training data used to generate autoregression terms.
  forecast : `pandas.DataFrame` or None
      Output of ``predict_silverkite``, set by ``self.predict``.
  forecast_x_mat : `pandas.DataFrame` or None
      The design matrix of the model at the predict time.
  model_summary : `class` or `None`
      The `~greykite.algo.common.model_summary.ModelSummary` class.
  
  See Also
  --------
  `~greykite.algo.forecast.silverkite.forecast_silverkite.SilverkiteForecast.forecast`
      Function performing the fit and predict.
  
  Notes
  -----
  The subclasses will pass ``fs_components_df`` to ``forecast_silverkite``. The model terms
  it creates internally are used to generate the component plots.
  
      - `~greykite.common.features.timeseries_features.fourier_series_multi_fcn` uses
        ``fs_components_df["names"]`` (e.g. ``tod``, ``tow``) to build the fourier series
        and to create column names.
  
      - ``fs_components_df["seas_names"]`` (e.g. ``daily``, ``weekly``) is appended
        to the column names, if provided.
  
  `~greykite.sklearn.estimator.base_silverkite_estimator.BaseSilverkiteEstimator.plot_components` relies
  on a regular expression dictionary to group components together.  There are two available in the library, see
  `~greykite.common.constants` for the two definitions
  
      1. "DEFAULT_COMPONENTS_REGEX_DICT"
         Grouped seasonality that is the default
      2. "DETAILED_SEASONALITY_COMPONENTS_REGEX_DICT":
         A detailed seasonality breakdown where the user can view daily/weekly/monthly/quarterly/yearly seasonality
docstr: Creates forecast for the dates specified in ``X``.
  
  Parameters
  ----------
  X: `pandas.DataFrame`
      Input timeseries with timestamp column and any additional regressors.
      Timestamps are the dates for prediction.
      Value column, if provided in ``X``, is ignored.
  y: ignored.
  
  Returns
  -------
  predictions: `pandas.DataFrame`
      Forecasted values for the dates in ``X``. Columns:
  
          - ``TIME_COL``: dates
          - ``PREDICTED_COL``: predictions
          - ``PREDICTED_LOWER_COL``: lower bound of predictions, optional
          - ``PREDICTED_UPPER_COL``: upper bound of predictions, optional
          - [other columns], optional
  
      ``PREDICTED_LOWER_COL`` and ``PREDICTED_UPPER_COL`` are present
      if ``self.coverage`` is not None.
code: def predict(self, X, y=None):
      """Creates forecast for the dates specified in ``X``.
  
      Parameters
      ----------
      X: `pandas.DataFrame`
          Input timeseries with timestamp column and any additional regressors.
          Timestamps are the dates for prediction.
          Value column, if provided in ``X``, is ignored.
      y: ignored.
  
      Returns
      -------
      predictions: `pandas.DataFrame`
          Forecasted values for the dates in ``X``. Columns:
  
              - ``TIME_COL``: dates
              - ``PREDICTED_COL``: predictions
              - ``PREDICTED_LOWER_COL``: lower bound of predictions, optional
              - ``PREDICTED_UPPER_COL``: upper bound of predictions, optional
              - [other columns], optional
  
          ``PREDICTED_LOWER_COL`` and ``PREDICTED_UPPER_COL`` are present
          if ``self.coverage`` is not None.
      """
      # Returns the cached result if applicable
      cached_predictions = super().predict(X=X)
      if cached_predictions is not None:
          return cached_predictions
  
      if self.model_dict is None:
          raise NotFittedError("Call `fit` before calling `predict`.")
      if self.pred_cols is None:
          raise NotFittedError(
              "Subclass must call `finish_fit` inside the `fit` method."
          )
  
      pred_res = self.silverkite.predict(
          fut_df=X,
          trained_model=self.model_dict,
          past_df=self.past_df,
          new_external_regressor_df=None,
      )  # regressors are included in X
      pred_df = pred_res["fut_df"]
      x_mat = pred_res["x_mat"]
      assert len(pred_df) == len(
          X
      ), "The returned prediction data must have same number of rows as the input ``X``"
      assert len(x_mat) == len(
          X
      ), "The returned design matrix (features matrix) must have same number of rows as the input ``X``"
  
      # Predicts the uncertainty model if not already fit.
      if self.uncertainty_model is not None:
          # The quantile regression model.
          if (
              self.uncertainty_dict.get("uncertainty_method")
              == UncertaintyMethodEnum.quantile_regression.name
          ):
              pred_df = self.predict_uncertainty(
                  df=pred_df.rename(
                      # The ``self.value_col_`` in ``pred_df`` is the predictions.
                      columns={self.value_col_: cst.PREDICTED_COL}
                  ),
                  predict_params=dict(x_mat=x_mat),
              )
  
          # In case prediction fails for uncertainty, uses the original output.
          if pred_df is None:
              pred_df = pred_res["fut_df"]
  
      self.forecast = pred_df
      self.forecast_x_mat = x_mat
  
      # Renames columns to standardized schema
      output_columns = {self.time_col_: cst.TIME_COL}
      if cst.PREDICTED_COL in pred_df.columns:
          output_columns[cst.PREDICTED_COL] = cst.PREDICTED_COL
      elif self.value_col_ in pred_df.columns:
          output_columns[self.value_col_] = cst.PREDICTED_COL
  
      # Checks if uncertainty by "simple_conditional_residuals" is also returned.
      # If so, extract the upper and lower limits of the tuples in
      # ``uncertainty_col`` to be lower and upper limits of the prediction interval.
      # Note that the tuple might have more than two elements if more than two
      # ``quantiles`` are passed in ``uncertainty_dict``.
      uncertainty_col = cst.QUANTILE_SUMMARY_COL
      if uncertainty_col in list(pred_df.columns):
          pred_df[cst.PREDICTED_LOWER_COL] = pred_df[
              uncertainty_col
          ].apply(lambda x: x[0])
          pred_df[cst.PREDICTED_UPPER_COL] = pred_df[
              uncertainty_col
          ].apply(lambda x: x[-1])
          # The following entries are to include the columns in the output,
          # they are not intended to rename the columns.
          output_columns.update({uncertainty_col: uncertainty_col})
          if cst.ERR_STD_COL in pred_df.columns:
              output_columns.update({cst.ERR_STD_COL: cst.ERR_STD_COL})
      # Checks if lower/upper columns are in the output df.
      # If so, includes these columns in the final output.
      if (
          cst.PREDICTED_LOWER_COL in pred_df.columns
          and cst.PREDICTED_UPPER_COL in pred_df.columns
      ):
          output_columns.update(
              {
                  cst.PREDICTED_LOWER_COL: cst.PREDICTED_LOWER_COL,
                  cst.PREDICTED_UPPER_COL: cst.PREDICTED_UPPER_COL,
              }
          )
  
      predictions = pred_df[output_columns.keys()].rename(
          output_columns, axis=1
      )
      # Caches the predictions
      self.cached_predictions_ = predictions
      return predictions
  
imports: import re
  from typing import Dict
  from typing import Optional
  from typing import Type
  import pandas
  import plotly.express
  from pandas.tseries.frequencies import to_offset
  from plotly import graph_objects
  from plotly.subplots import make_subplots
  from sklearn.exceptions import NotFittedError
  from sklearn.metrics import mean_squared_error
  from greykite.algo.changepoint.adalasso.changepoints_utils import get_trend_changepoint_dates_from_cols
  from greykite.algo.common.col_name_utils import create_pred_category
  from greykite.algo.common.ml_models import breakdown_regression_based_prediction
  from greykite.algo.common.model_summary import ModelSummary
  from greykite.algo.forecast.silverkite.constants.silverkite_component import SilverkiteComponentsEnum
  from greykite.algo.forecast.silverkite.constants.silverkite_constant import default_silverkite_constant
  from greykite.algo.forecast.silverkite.forecast_silverkite import SilverkiteForecast
  from greykite.algo.forecast.silverkite.forecast_silverkite_helper import get_silverkite_uncertainty_dict
  from greykite.common import constants
  from greykite.common.features.timeseries_lags import min_max_lag_order
  from greykite.common.time_properties import min_gap_in_seconds
  from greykite.common.time_properties_forecast import get_simple_time_frequency_from_period
  from greykite.sklearn.estimator.base_forecast_estimator import BaseForecastEstimator
  from greykite.sklearn.uncertainty.uncertainty_methods import UncertaintyMethodEnum
label_desc: Use image node_id 5 for calling the BaseSilverkiteEstimator obj's underlying member method code with example usage: obj.predict(X, y) and returns: predictions, cached_predictions