class_docstr: Metrics that can be used to evaluate the following fairness metrics.
  
    * Demographic Parity or Equality of Outcomes.
      For each slice measure the Positive* Rate, or the percentage of all
      examples receiving positive scores.
    * Equality of Opportunity
      Equality of Opportunity attempts to match the True Positive* rate
      (aka recall) of different data slices.
    * Equality of Odds
      In addition to looking at Equality of Opportunity, looks at equalizing the
      False Positive* rates of slices as well.
  
  The choice to focus on these metrics as a starting point is based primarily on
  the paper Equality of Opportunity in Supervised Learning and the excellent
  visualization created as a companion to the paper.
  
  https://arxiv.org/abs/1610.02413
  http://research.google.com/bigpicture/attacking-discrimination-in-ml/
  
  * Note that these fairness formulations assume that a positive prediction is
  associated with a positive outcome for the user--in certain contexts such as
  abuse, positive predictions translate to non-opportunity. You may want to use
  the provided negative rates for comparison instead.
class_docstr_tok: ["Metrics","that","can","be","used","to","evaluate","the","following","fairness","metrics",".","*","Demographic","Parity","or","Equality","of","Outcomes",".","For","each","slice","measure","the","Positive","*","Rate",",","or","the","percentage","of","all","examples","receiving","positive","scores",".","*","Equality","of","Opportunity","Equality","of","Opportunity","attempts","to","match","the","True","Positive","*","rate","(","aka","recall",")","of","different","data","slices",".","*","Equality","of","Odds","In","addition","to","looking","at","Equality","of","Opportunity",",","looks","at","equalizing","the","False","Positive","*","rates","of","slices","as","well",".","The","choice","to","focus","on","these","metrics","as","a","starting","point","is","based","primarily","on","the","paper","Equality","of","Opportunity","in","Supervised","Learning","and","the","excellent","visualization","created","as","a","companion","to","the","paper",".","https",":","\/\/arxiv.org\/abs\/1610.02413","http",":","\/\/research.google.com\/bigpicture\/attacking-discrimination-in-ml\/","*","Note","that","these","fairness","formulations","assume","that","a","positive","prediction","is","associated","with","a","positive","outcome","for","the","user","--","in","certain","contexts","such","as","abuse",",","positive","predictions","translate","to","non-opportunity",".","You","may","want","to","use","the","provided","negative","rates","for","comparison","instead","."]
code: def get_metric_ops(
      self,
      features_dict: types.TensorTypeMaybeDict,
      predictions_dict: types.TensorTypeMaybeDict,
      labels_dict: types.TensorTypeMaybeDict,
  ) -> Dict[str, Tuple[types.TensorType, types.TensorType]]:
      values, update_ops = self.confusion_matrix_metric_ops(
          features_dict, predictions_dict, labels_dict
      )
      # True positive rate is computed by confusion_matrix_metric_ops as 'recall'.
      # pytype: disable=unsupported-operands
      values["tnr"] = tf.math.divide_no_nan(
          values["tn"], values["tn"] + values["fp"]
      )
      values["fpr"] = tf.math.divide_no_nan(
          values["fp"], values["fp"] + values["tn"]
      )
      values["positive_rate"] = tf.math.divide_no_nan(
          values["tp"] + values["fp"],
          values["tp"] + values["fp"] + values["tn"] + values["fn"],
      )
      values["fnr"] = tf.math.divide_no_nan(
          values["fn"], values["fn"] + values["tp"]
      )
      values["negative_rate"] = tf.math.divide_no_nan(
          values["tn"] + values["fn"],
          values["tp"] + values["fp"] + values["tn"] + values["fn"],
      )
  
      values["false_discovery_rate"] = tf.math.divide_no_nan(
          values["fp"], values["fp"] + values["tp"]
      )
      values["false_omission_rate"] = tf.math.divide_no_nan(
          values["fn"], values["fn"] + values["tn"]
      )
  
      # pytype: enable=unsupported-operands
  
      update_op = tf.group(
          update_ops["fn"],
          update_ops["tn"],
          update_ops["fp"],
          update_ops["tp"],
      )
      value_op = tf.transpose(
          a=tf.stack(
              [
                  values["fn"],
                  values["tn"],
                  values["fp"],
                  values["tp"],
                  values["precision"],
                  values["recall"],
              ]
          )
      )
  
      output_dict = {
          self._metric_key(self.matrices_key): (value_op, update_op),
          self._metric_key(self.thresholds_key): (
              tf.identity(self._thresholds),
              tf.no_op(),
          ),
      }
      for i, threshold in enumerate(self._thresholds):
          output_dict[
              self._metric_key(
                  metric_keys.base_key(
                      "positive_rate@%.*f"
                      % (self._key_digits, threshold)
                  )
              )
          ] = (values["positive_rate"][i], update_op)
          output_dict[
              self._metric_key(
                  metric_keys.base_key(
                      "true_positive_rate@%.*f"
                      % (self._key_digits, threshold)
                  )
              )
          ] = (values["recall"][i], update_op)
          output_dict[
              self._metric_key(
                  metric_keys.base_key(
                      "false_positive_rate@%.*f"
                      % (self._key_digits, threshold)
                  )
              )
          ] = (values["fpr"][i], update_op)
          output_dict[
              self._metric_key(
                  metric_keys.base_key(
                      "negative_rate@%.*f"
                      % (self._key_digits, threshold)
                  )
              )
          ] = (values["negative_rate"][i], update_op)
          output_dict[
              self._metric_key(
                  metric_keys.base_key(
                      "true_negative_rate@%.*f"
                      % (self._key_digits, threshold)
                  )
              )
          ] = (values["tnr"][i], update_op)
          output_dict[
              self._metric_key(
                  metric_keys.base_key(
                      "false_negative_rate@%.*f"
                      % (self._key_digits, threshold)
                  )
              )
          ] = (values["fnr"][i], update_op)
          output_dict[
              self._metric_key(
                  metric_keys.base_key(
                      "false_discovery_rate@%.*f"
                      % (self._key_digits, threshold)
                  )
              )
          ] = (values["false_discovery_rate"][i], update_op)
          output_dict[
              self._metric_key(
                  metric_keys.base_key(
                      "false_omission_rate@%.*f"
                      % (self._key_digits, threshold)
                  )
              )
          ] = (values["false_omission_rate"][i], update_op)
      return output_dict
  
file_path: model-analysis/tensorflow_model_analysis/addons/fairness/post_export_metrics/fairness_indicators.py
imports: from typing import Any, Dict, List, Optional, Tuple
  import tensorflow
  from tensorflow_model_analysis.api import types
  from tensorflow_model_analysis.post_export_metrics import metric_keys
  from tensorflow_model_analysis.post_export_metrics import post_export_metrics
  from tensorflow_model_analysis.proto import metrics_for_slice_pb2
  from tensorflow_model_analysis.slicer import slicer_lib
label_desc: Use image node_id 2 for calling the _FairnessIndicators obj's underlying member method code with example usage: obj.get_metric_ops(features_dict, predictions_dict, labels_dict) and returns: output_dict