class_docstr: Calibrated equalized odds postprocessing is a post-processing technique
  that optimizes over calibrated classifier score outputs to find
  probabilities with which to change output labels with an equalized odds
  objective [7]_.
  
  References:
      .. [7] G. Pleiss, M. Raghavan, F. Wu, J. Kleinberg, and
         K. Q. Weinberger, "On Fairness and Calibration," Conference on Neural
         Information Processing Systems, 2017
  
  Adapted from:
  https://github.com/gpleiss/equalized_odds_and_calibration/blob/master/calib_eq_odds.py
docstr: Perturb the predicted scores to obtain new labels that satisfy
  equalized odds constraints, while preserving calibration.
  
  Args:
      dataset (BinaryLabelDataset): Dataset containing `scores` that needs
          to be transformed.
      threshold (float): Threshold for converting `scores` to `labels`.
          Values greater than or equal to this threshold are predicted to
          be the `favorable_label`. Default is 0.5.
  Returns:
      dataset (BinaryLabelDataset): transformed dataset.
code: def predict(self, dataset, threshold=0.5):
      """Perturb the predicted scores to obtain new labels that satisfy
      equalized odds constraints, while preserving calibration.
  
      Args:
          dataset (BinaryLabelDataset): Dataset containing `scores` that needs
              to be transformed.
          threshold (float): Threshold for converting `scores` to `labels`.
              Values greater than or equal to this threshold are predicted to
              be the `favorable_label`. Default is 0.5.
      Returns:
          dataset (BinaryLabelDataset): transformed dataset.
      """
      if self.seed is not None:
          np.random.seed(self.seed)
  
      cond_vec_priv = utils.compute_boolean_conditioning_vector(
          dataset.protected_attributes,
          dataset.protected_attribute_names,
          self.privileged_groups,
      )
      cond_vec_unpriv = utils.compute_boolean_conditioning_vector(
          dataset.protected_attributes,
          dataset.protected_attribute_names,
          self.unprivileged_groups,
      )
  
      unpriv_indices = (
          np.random.random(sum(cond_vec_unpriv)) <= self.unpriv_mix_rate
      )
      unpriv_new_pred = dataset.scores[cond_vec_unpriv].copy()
      unpriv_new_pred[unpriv_indices] = self.base_rate_unpriv
  
      priv_indices = (
          np.random.random(sum(cond_vec_priv)) <= self.priv_mix_rate
      )
      priv_new_pred = dataset.scores[cond_vec_priv].copy()
      priv_new_pred[priv_indices] = self.base_rate_priv
  
      dataset_new = dataset.copy(deepcopy=True)
  
      dataset_new.scores = np.zeros_like(
          dataset.scores, dtype=np.float64
      )
      dataset_new.scores[cond_vec_priv] = priv_new_pred
      dataset_new.scores[cond_vec_unpriv] = unpriv_new_pred
  
      # Create labels from scores using a default threshold
      dataset_new.labels = np.where(
          dataset_new.scores >= threshold,
          dataset_new.favorable_label,
          dataset_new.unfavorable_label,
      )
      return dataset_new
  
file_path: AIF360/aif360/algorithms/postprocessing/calibrated_eq_odds_postprocessing.py
imports: import numpy
  from aif360.algorithms import Transformer
  from aif360.metrics import ClassificationMetric, utils
label_desc: Use image node_id 3 for calling the CalibratedEqOddsPostprocessing obj's underlying member method code with example usage: obj.predict(dataset, threshold) and returns: dataset_new