code: def _evaluate(
      ground_truth: pd.Series,
      classifier: pd.Series,
      prot_attr: pd.Series = None,
      num_iters=1e5,
      cost_matrix: np.ndarray = None,
      **kwargs,
  ):
      """calculate Wasserstein distance between groups defined by `prot_attr` in `ground_truth` and `classifier`.
  
      Args:
          ground_truth (pd.Series, str): ground truth (correct) target value
          classifier (pd.Series): estimated target values
          prot_attr (pd.Series, str): pandas series of sensitive attribute values
          num_iters (int, optional): number of iterations (random restarts). Should be positive.
  
      Returns:
          ot.emd2 (float, dict): Earth mover's distance or dictionary of optimal transports for each of option of classifier
      """
  
      # Calculate just the EMD between ground_truth and classifier
      if prot_attr is None:
          (
              initial_distribution,
              required_distribution,
              matrix_distance,
          ) = _transform(ground_truth, classifier, cost_matrix)
          return ot.emd2(
              a=initial_distribution,
              b=required_distribution,
              M=matrix_distance,
              numItermax=num_iters,
          )
  
      if not ground_truth.nunique() == 2:
          raise ValueError(
              f"Expected to have exactly 2 target values, got {ground_truth.nunique()}."
          )
  
      # Calculate EMD between ground truth distribution and distribution of each group
      emds = {}
      for sa_val in sorted(prot_attr.unique()):
          initial_distribution = ground_truth[prot_attr == sa_val]
          required_distribution = classifier[prot_attr == sa_val]
          (
              initial_distribution,
              required_distribution,
              matrix_distance,
          ) = _transform(
              initial_distribution, required_distribution, cost_matrix
          )
          emds[sa_val] = ot.emd2(
              a=initial_distribution,
              b=required_distribution,
              M=matrix_distance,
              numItermax=num_iters,
          )
  
      return emds
  
file_path: AIF360/aif360/metrics/ot_metric.py
imports: from typing import Union
  import pandas
  import numpy
  import ot
  from sklearn.preprocessing import LabelEncoder
label_desc: Use image node_id 3 for calling a global function with example usage: _evaluate(ground_truth, classifier, prot_attr, num_iters, cost_matrix) and returns: emds, ot