class_docstr: Base detector class for Anomaly Detection.
  The class initializes by passing an arbitrary ``reward`` for optimization
  and a potentially multivariate parameter (given in ``param_iterable``) to optimize.
  
  The ``reward`` object is required to implement the ``apply`` method which is the case for this class:
  `~greykite.detection.detector.reward.Reward`
  
  The class behaves similar to typical machine-learning algorithms as it includes
  
      - ``fit``
      - ``predict``
  
  methods.
  
  The optimization method (``optimize_param``) is inherited from:
  
  `~greykite.detection.detector.optimizer.Optimizer`
  
  It works simply by iterating over ``param_iterable`` and calculating
  the reward to choose the optimal parameter via ``calc_with_param`` method
  which is an abstract method already appearing in the ``Optimizer`` class.
  
  The class assumes that larger is better for the reward function,
  during optimization.
  
  The classes inheriting this class, need to implement ``calc_with_param``
  method to be able to use the optimizer and given that implementation.
  
  The ``predict`` method is already implemented here and should work for most cases.
  This is because in most cases, ``predict`` is simply ``calc_with_param``
  applied to the best param found during the optimization step.
  
  Parameters
  ----------
  reward : `~greykite.detection.detector.reward.Reward` or None, default None
      The reward to be used in the optimization.
      If None, an reward will be built using the other input
      ``anomaly_percent_dict``.
  
  anomaly_percent_dict : `dict` or None, default None
      If not None, a dictionary with items:
  
      - ``"range"`` : `tuple`
          We expect a tuple with two elements denoting the min and max
          of the interval range.
      - ``"penalty"`` : `float`
          A real number to specify the penalty of being outside the range
          specified by user. It should be typically a negative value and it
          could be set to ``float("-inf")`` to make this reward a restriction
          while using it along with other rewards.
  
      which is used to construct an reward which will be the reward in
      the optimization is no reward is passed.
      If another reward is passed then this will be added to the passed reward.
      The constructed reward based on ``anomaly_percent_dict`` penalizes
      by the distance between the center of the ``"range"`` and predicted anomaly
      percent as long as the predicted is within range.
      For values outside the range an extra penalty given in``"penalty"`` will be applied.
      If `"penalty"` is None, it will be set to -1.
  
  param_iterable : iterable or None, default None
      An iterable with every element being a parameter passed to the method
      ``calc_with_param`` which takes ``param`` as one of its arguments.
      Each `param` can be a dictionary including values for a set of variables,
      but that is not a requirement.
      The optimizer method (``optimize_param``) will iterate over all the
      parameters to find the best parameter in terms of the specified reward.
  
  Attributes
  ----------
  data : `dataclasses.dataclass` or None, default None
      A data class object which includes the data for fitting or
      prediction. Depending on the model, this data class might
      include various fields. The prominent used class which can support
      forecast based approaches is given in
      `~greykite.detection.detector.DetectorData`.
  fitted_df : `pandas.DataFrame` or None, default None
      The fitted data after applying the detector.
  fit_info : `dict`
      A dictionary which includes information about the fitted model.
      It is expected that this includes ``"full_param"`` after the fitting
      so that the ``predict`` function can use that param during the prediction
      and simply call ``calc_with_param``.
      In that case the ``predict`` function does not need further implementation
      in child classes as it's already implemented in this class.
docstr: ``predict`` method is already implemented here and should work for most cases.
      This is because in most cases, ``predict`` is simply
      ``calc_with_param`` applied to the best param found during optimization.
  
  Parameters
  ----------
  data : See class attributes.
  
  Returns
  -------
  result : return type of ``calc_with_param``
      Usually a ``pandas.DataFrame`` which includes the predicted anomalies.
docstr_tok: ["``","predict","``","method","is","already","implemented","here","and","should","work","for","most","cases",".","This","is","because","in","most","cases",",","``","predict","``","is","simply","``","calc_with_param","``","applied","to","the","best","param","found","during","optimization",".","Parameters","--","--","--","--","--","data",":","See","class","attributes",".","Returns","--","--","--","-","result",":","return","type","of","``","calc_with_param","``","Usually","a","``","pandas.DataFrame","``","which","includes","the","predicted","anomalies","."]
code: def predict(self, data, **kwargs):
      """``predict`` method is already implemented here and should work for most cases.
          This is because in most cases, ``predict`` is simply
          ``calc_with_param`` applied to the best param found during optimization.
  
      Parameters
      ----------
      data : See class attributes.
  
      Returns
      -------
      result : return type of ``calc_with_param``
          Usually a ``pandas.DataFrame`` which includes the predicted anomalies.
      """
      self.prep_df_for_predict(data)
      calc_result = self.calc_with_param(
          data=data, param=self.fit_info["param_full"], **kwargs
      )
      if data is not None:
          self.pred_df = calc_result.data.pred_df
      return calc_result.data
  
imports: import numpy
  import pandas
  from greykite.common.constants import ACTUAL_COL
  from greykite.common.constants import ANOMALY_COL
  from greykite.common.constants import END_TIME_COL
  from greykite.common.constants import PREDICTED_ANOMALY_COL
  from greykite.common.constants import PREDICTED_COL
  from greykite.common.constants import PREDICTED_LOWER_COL
  from greykite.common.constants import PREDICTED_UPPER_COL
  from greykite.common.constants import START_TIME_COL
  from greykite.common.constants import TIME_COL
  from greykite.common.viz.timeseries_annotate import plot_anomalies_over_forecast_vs_actual
  from greykite.detection.common.ad_evaluation import f1_score
  from greykite.detection.common.ad_evaluation import precision_score
  from greykite.detection.common.ad_evaluation import recall_score
  from greykite.detection.detector.ad_utils import get_anomaly_df
  from greykite.detection.detector.ad_utils import partial_return
  from greykite.detection.detector.constants import PHASE_PREDICT
  from greykite.detection.detector.constants import PHASE_TRAIN
  from greykite.detection.detector.constants import PenalizeMethod
  from greykite.detection.detector.optimizer import Optimizer
  from greykite.detection.detector.reward import Reward
label_desc: Use image node_id 4 for calling the Detector obj's underlying member method code with example usage: obj.predict(data) and returns: calc_result