class_docstr: Wrapper for running a grid search over threshold, margin combinations for
  a RejectOptionClassifier.
  
  Note:
      :class:`~sklearn.model_selection.GridSearchCV` does not currently
      support sample weights in scoring. This will work but throw a warning if
      `sample_weight` is provided.
  
  See also:
      :class:`RejectOptionClassifier`
  
  Examples:
      >>> import matplotlib.pyplot as plt
      >>> import pandas as pd
      >>> from sklearn.linear_model import LogisticRegression
      >>> from aif360.sklearn.datasets import fetch_german
      >>> from aif360.sklearn.postprocessing import RejectOptionClassifierCV
      >>> X, y = fetch_german(numeric_only=True)
      >>> lr = LogisticRegression(solver='lbfgs').fit(X, y)
      >>> roc = RejectOptionClassifierCV('sex', scoring='disparate_impact')
      >>> roc.fit(pd.DataFrame(lr.predict_proba(X), index=X.index), y)
  
      We can also achieve this more simply using a PostProcessingMeta
      estimator:
  
      >>> from aif360.sklearn.postprocessing import PostProcessingMeta
      >>> pp = PostProcessingMeta(lr, roc).fit(X, y)
docstr: Run fit with all sets of parameters.
  
  Args:
      X (pandas.DataFrame): Probability estimates of the targets as
          returned by a ``predict_proba()`` call or equivalent. Note: must
          include protected attributes in the index.
      y (pandas.Series): Ground-truth (correct) target values.
      **fit_params: Parameters passed to the ``fit()`` method.
  
  Returns:
      self
docstr_tok: ["Run","fit","with","all","sets","of","parameters",".","Args",":","X","(","pandas.DataFrame",")",":","Probability","estimates","of","the","targets","as","returned","by","a","``","predict_proba","(",")","``","call","or","equivalent",".","Note",":","must","include","protected","attributes","in","the","index",".","y","(","pandas.Series",")",":","Ground-truth","(","correct",")","target","values",".","*","*","fit_params",":","Parameters","passed","to","the","``","fit","(",")","``","method",".","Returns",":","self"]
code: def fit(self, X, y, **fit_params):
      """Run fit with all sets of parameters.
  
      Args:
          X (pandas.DataFrame): Probability estimates of the targets as
              returned by a ``predict_proba()`` call or equivalent. Note: must
              include protected attributes in the index.
          y (pandas.Series): Ground-truth (correct) target values.
          **fit_params: Parameters passed to the ``fit()`` method.
  
      Returns:
          self
      """
      self.param_grid = []
      thresholds = np.arange(self.step, 1, self.step)
      # arange has numerical instabilities. this way guarantees margin <= threshold
      for i, t in enumerate(thresholds):
          n = min(i + 1, len(thresholds) - i)
          margins = np.linspace(
              min(self.step, min(t, 1 - t)), min(t, 1 - t), n
          )
          self.param_grid.append(
              {
                  "prot_attr": [self.prot_attr],
                  "threshold": [t],
                  "margin": margins,
              }
          )
  
      if fit_params.get("sample_weight", None) is not None:
          warnings.warn(
              "sample_weight will be ignored when scoring.",
              RuntimeWarning,
          )
  
      if not isinstance(self.scoring, dict):
          # TODO: sample_weight scoring workaround
          self.scorer_name_ = self.scoring
          if self.scoring == "statistical_parity":
              self.scorer_ = make_scorer(
                  statistical_parity_difference,
                  prot_attr=self.prot_attr,
              )
          elif self.scoring == "average_odds":
              self.scorer_ = make_scorer(
                  average_odds_error, prot_attr=self.prot_attr
              )
          elif self.scoring == "equal_opportunity":
              self.scorer_ = make_scorer(
                  equal_opportunity_difference, prot_attr=self.prot_attr
              )
          elif self.scoring == "disparate_impact":
              self.scorer_ = make_scorer(
                  disparate_impact_ratio,
                  is_ratio=True,
                  prot_attr=self.prot_attr,
                  zero_division=0,
              )
          elif not callable(self.scoring):
              raise ValueError(
                  "scorer must be one of: 'statistical_parity', "
                  "'average_odds', 'equal_opportunity', 'disparate_impact' "
                  "or a callable function. Got:\n{}".format(
                      self.scoring
                  )
              )
          else:
              self.scorer_name_ = "fairness_metric"
              self.scorer_ = self.scoring
  
          self.scoring = {
              "bal_acc": "balanced_accuracy",
              self.scorer_name_: self.scorer_,
          }
  
      if self.refit is True and self.scorer_name_ != "fairness_metric":
          if self.scorer_name_ == "disparate_impact":
              self.refit = lambda res: np.ma.array(
                  res["mean_test_bal_acc"],
                  mask=res["mean_test_disparate_impact"] < 0.8,
              ).argmax()
          else:
              self.refit = lambda res: np.ma.array(
                  res["mean_test_bal_acc"],
                  mask=res["mean_test_" + self.scorer_name_] < -0.1,
              ).argmax()
  
      class NoSplit:
          def split(self, X, y=None, groups=None):
              yield np.arange(len(X)), np.arange(len(X))
  
          def get_n_splits(self, X=None, y=None, groups=None):
              return 1
  
      self.cv = NoSplit()
  
      return super().fit(X, y, **fit_params)
  
imports: import warnings
  import numpy
  from sklearn.base import BaseEstimator, ClassifierMixin
  from sklearn.model_selection import GridSearchCV
  from sklearn.utils.validation import check_is_fitted
  from aif360.sklearn.metrics import statistical_parity_difference
  from aif360.sklearn.metrics import average_odds_error
  from aif360.sklearn.metrics import equal_opportunity_difference
  from aif360.sklearn.metrics import disparate_impact_ratio
  from aif360.sklearn.metrics import make_scorer
  from aif360.sklearn.utils import check_groups
label_desc: Use image node_id 3 for calling the RejectOptionClassifierCV obj's underlying member method code with example usage: obj.fit(X, y) and returns: super, int