class_docstr: Forecast one-by-one estimator.
  
  Parameters
  ----------
  score_func : `callable`, default mean_squared_error
      Function to calculate model R2_null_model_score score,
      with signature (actual, predicted).
      ``actual``, ``predicted`` are array-like with the same shape.
      Smaller values are better.
  
  coverage : `float`, default 0.95
      Intended coverage of the prediction bands (0.0 to 1.0).
      If None, the upper/lower predictions are not returned by ``predict``.
  
  null_model_params : `dict`, default None
      Dictionary keys must be in ("strategy", "constant", "quantile").
      Defines null model. model score is R2_null_model_score of model error relative to null model,
      evaluated by score_func.
      If None, model score is score_func of the model itself.
  
  estimator : `str`
      The estimator used in forecast one-by-one.
      Must be one of the keys in ``ONEBYONE_ESTIMATORS``.
  
  forecast_horizon : `int`
      The forecast horizon.
  
  estimator_map : `bool`, `int` or `list` [`int`], default None
      The map between estimators and forecast horizons.
  
          If True, each time point in the forecasting period has a different model.
          If False, forecast one-by-one is turned off.
          If `int`, every ``estimator_map`` time points have a different model.
          If `list`, the sum must equal to the forecast horizon.
              The values are the number of timepoints in each estimator.
  
      For example, if forecast horizon is 7
  
          `estimator_map = True` corresponds to [1, 1, 1, 1, 1, 1, 1], 7 models.
          `estimator_map = 1` corresponds to [1, 1, 1, 1, 1, 1, 1], 7 models.
          `estimator_map = 2` corresponds to [2, 2, 2, 1], 4 models.
          `estimator_map = [1, 2, 4]` corresponds to 3 models.
          `estimator_map = False` corresponds to [7], 1 model.
          `estimator_map = None` corresponds to [7], 1 model.
  
  
  Attributes
  ----------
  estimator : `str`
      The estimator name.
  estimator_params : `dict`
      The parameters used in the estimator.
  forecast_horizon : `int`
      The forecast horizon.
  estimator_map : `bool`, `int`, `list` [`int]`
      The map between estimators and time points.
  estimator_map_list : `list` [`int`]
      The processed estimator_map as a list.
      We don't want to overwrite the original self.estimator_map.
  estimator_param_names : `list` [`str`]
      All available parameter names in estimator.
  estimator_class : `class`
      The estimator class.
  estimators : `list` [`class`]
      The list of estimator class instances.
  model_results : `list`
      The list of estimator fit method outputs.
  pred_indices : `list` [`int`]
      The list of indices used to splice forecasts.
  forecast : `pandas.DataFrame`
      The cached forecast results from the last call of ``self.predict``.
docstr: Creates forecast for dates specified in X
  
  The forecast one-by-one is supposed to forecast for the specified forecast horizon
  with the specified estimator-horizon mapping. If the size of ``X`` is different from
  forecast horizon, only the last model (trained with the longest forecast horizon)
  will be used.
  
  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.
docstr_tok: ["Creates","forecast","for","dates","specified","in","X","The","forecast","one-by-one","is","supposed","to","forecast","for","the","specified","forecast","horizon","with","the","specified","estimator-horizon","mapping",".","If","the","size","of","``","X","``","is","different","from","forecast","horizon",",","only","the","last","model","(","trained","with","the","longest","forecast","horizon",")","will","be","used",".","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 dates specified in X
  
      The forecast one-by-one is supposed to forecast for the specified forecast horizon
      with the specified estimator-horizon mapping. If the size of ``X`` is different from
      forecast horizon, only the last model (trained with the longest forecast horizon)
      will be used.
  
      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
  
      # Only one model.
      if len(self.estimators) == 1:
          return self.estimators[0].predict(X=X)
  
      # Forecast one-by-one is forecast-horizon-sensitive.
      # Checks future forecast horizon length to decide
      # how to make forecasts.
      is_future = (
          pd.to_datetime(X[self.time_col_]) > self.train_end_date
      )
      x_future = X.loc[is_future]
  
      # If the future prediction length is different from the forecast horizon,
      # use the last model only.
      if len(x_future) != self.forecast_horizon:
          log_message(
              message=f"The future x length is {len(x_future)}, "
              f"which doesn't match the model forecast horizon {self.forecast_horizon}, "
              f"using only the model with the longest forecast horizon for prediction.",
              level=LoggingLevelEnum.WARNING,
          )
          return self.estimators[-1].predict(X)
  
      # The past df is always forecasted with the last estimator.
      past_prediction = None
      if not is_future.all():
          past_prediction = self.estimators[-1].predict(
              X.loc[~is_future]
          )
  
      # From now on assume ``x_future`` is exactly the forecast horizon.
      # Makes predictions according to the estimator map.
      predictions = [
          estimator.predict(
              x_future.iloc[
                  self.pred_indices[i] : self.pred_indices[i + 1]
              ]
          )
          for i, estimator in enumerate(self.estimators)
      ]
      predictions = pd.concat(
          [past_prediction] + predictions, axis=0
      ).reset_index(drop=True)
      self.forecast = predictions
  
      return predictions
  
imports: from copy import deepcopy
  from typing import Callable
  from typing import List
  from typing import Optional
  from typing import Union
  import pandas
  from sklearn.metrics import mean_squared_error
  from greykite.common import constants
  from greykite.common.logging import LoggingLevelEnum
  from greykite.common.logging import log_message
  from greykite.sklearn.estimator.base_forecast_estimator import BaseForecastEstimator
  from greykite.sklearn.estimator.prophet_estimator import ProphetEstimator
  from greykite.sklearn.estimator.silverkite_estimator import SilverkiteEstimator
  from greykite.sklearn.estimator.simple_silverkite_estimator import SimpleSilverkiteEstimator
label_desc: Use image node_id 5 for calling the OneByOneEstimator obj's underlying member method code with example usage: obj.predict(X, y) and returns: predictions, cached_predictions, self, self