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: Compute parameters for equalizing generalized odds using true and
  predicted scores, while preserving calibration.
  
  Args:
      dataset_true (BinaryLabelDataset): Dataset containing true `labels`.
      dataset_pred (BinaryLabelDataset): Dataset containing predicted
          `scores`.
  
  Returns:
      CalibratedEqOddsPostprocessing: Returns self.
code: def fit(self, dataset_true, dataset_pred):
      """Compute parameters for equalizing generalized odds using true and
      predicted scores, while preserving calibration.
  
      Args:
          dataset_true (BinaryLabelDataset): Dataset containing true `labels`.
          dataset_pred (BinaryLabelDataset): Dataset containing predicted
              `scores`.
  
      Returns:
          CalibratedEqOddsPostprocessing: Returns self.
      """
  
      # Create boolean conditioning vectors for protected groups
      cond_vec_priv = utils.compute_boolean_conditioning_vector(
          dataset_pred.protected_attributes,
          dataset_pred.protected_attribute_names,
          self.privileged_groups,
      )
      cond_vec_unpriv = utils.compute_boolean_conditioning_vector(
          dataset_pred.protected_attributes,
          dataset_pred.protected_attribute_names,
          self.unprivileged_groups,
      )
  
      cm = ClassificationMetric(
          dataset_true,
          dataset_pred,
          unprivileged_groups=self.unprivileged_groups,
          privileged_groups=self.privileged_groups,
      )
      self.base_rate_priv = cm.base_rate(privileged=True)
      self.base_rate_unpriv = cm.base_rate(privileged=False)
  
      # Create a dataset with "trivial" predictions
      dataset_trivial = dataset_pred.copy(deepcopy=True)
      dataset_trivial.scores[cond_vec_priv] = cm.base_rate(
          privileged=True
      )
      dataset_trivial.scores[cond_vec_unpriv] = cm.base_rate(
          privileged=False
      )
      cm_triv = ClassificationMetric(
          dataset_true,
          dataset_trivial,
          unprivileged_groups=self.unprivileged_groups,
          privileged_groups=self.privileged_groups,
      )
  
      if self.fn_rate == 0:
          priv_cost = cm.generalized_false_positive_rate(
              privileged=True
          )
          unpriv_cost = cm.generalized_false_positive_rate(
              privileged=False
          )
          priv_trivial_cost = cm_triv.generalized_false_positive_rate(
              privileged=True
          )
          unpriv_trivial_cost = cm_triv.generalized_false_positive_rate(
              privileged=False
          )
  
      elif self.fp_rate == 0:
          priv_cost = cm.generalized_false_negative_rate(
              privileged=True
          )
          unpriv_cost = cm.generalized_false_negative_rate(
              privileged=False
          )
          priv_trivial_cost = cm_triv.generalized_false_negative_rate(
              privileged=True
          )
          unpriv_trivial_cost = cm_triv.generalized_false_negative_rate(
              privileged=False
          )
  
      else:
          priv_cost = weighted_cost(
              self.fp_rate, self.fn_rate, cm, privileged=True
          )
          unpriv_cost = weighted_cost(
              self.fp_rate, self.fn_rate, cm, privileged=False
          )
          priv_trivial_cost = weighted_cost(
              self.fp_rate, self.fn_rate, cm_triv, privileged=True
          )
          unpriv_trivial_cost = weighted_cost(
              self.fp_rate, self.fn_rate, cm_triv, privileged=False
          )
  
      unpriv_costs_more = unpriv_cost > priv_cost
      self.priv_mix_rate = (
          (unpriv_cost - priv_cost) / (priv_trivial_cost - priv_cost)
          if unpriv_costs_more
          else 0
      )
      self.unpriv_mix_rate = (
          0
          if unpriv_costs_more
          else (priv_cost - unpriv_cost)
          / (unpriv_trivial_cost - unpriv_cost)
      )
  
      return self
  
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 2 for calling the CalibratedEqOddsPostprocessing obj's underlying member method code with example usage: obj.fit(dataset_true, dataset_pred) and returns: self