class_docstr: Computes label and prediction pairs for set matching.
code: def process(
      self, extracts: types.Extracts
  ) -> Iterator[metric_types.StandardMetricInputs]:
      extracts = util.StandardExtracts(extracts)
  
      labels = extracts.get_labels(self._model_name)
  
      if labels is None or labels.ndim != 1:
          raise ValueError(
              f"Labels must be a 1d numpy array. The classes are {labels}."
          )
  
      # classes and weights are two lists representing the class wise weights.
      classes = None
      weights = None
      if self._weight_key:
          features = extracts.get_features()
          if features is None:
              raise ValueError(
                  'Weights should be under "features" key. However, features is None'
              )
          weights = util.get_by_keys(features, [self._weight_key])
          if self._class_key:
              classes = util.get_by_keys(features, [self._class_key])
          else:
              classes = labels
  
          if classes is None or not isinstance(classes, np.ndarray):
              raise TypeError(
                  "The classes for class-weight pair should be a numpy"
                  f" array. The classes are {classes}."
              )
          if weights is None or not isinstance(weights, np.ndarray):
              raise TypeError(
                  "The classes for class_weight pair should be a numpy"
                  f" array. The classes are {weights}."
              )
          if classes.shape != weights.shape:
              raise ValueError(
                  "Classes and weights must be of the same shape."
                  f" Classes and weights are {classes} and {weights}."
              )
  
      predictions = extracts.get_predictions(
          model_name=self._model_name
      )
      if not isinstance(predictions, dict):
          raise TypeError(
              "Predictions are expected to be a dictionary conatining "
              "classes and scores."
          )
  
      pred_classes = util.get_by_keys(
          predictions, [self._prediction_class_key]
      )
      if pred_classes is None:
          raise KeyError(
              f"Key {self._prediction_class_key} is not found under "
              "predictions of the extracts."
          )
  
      pred_scores = None
      if self._prediction_score_key:
          pred_scores = util.get_by_keys(
              predictions, [self._prediction_score_key]
          )
          if pred_scores is None:
              raise KeyError(
                  f"Key {self._prediction_score_key} is not found under "
                  "predictions of the extracts."
              )
  
          if pred_classes.shape != pred_scores.shape:
              raise ValueError(
                  "Classes and scores must be of the same shape. Classes and scores "
                  f"are {pred_classes} and {pred_scores}."
              )
  
      if pred_classes.ndim != 1:
          raise ValueError(
              "Predicted classes must be a 1d numpy array. The classes are "
              f"{pred_classes}."
          )
  
      if self._top_k is not None:
          if self._top_k > len(pred_classes):
              self._model_top_k_exceeds_prediction_length_distribution.update(
                  len(pred_classes)
              )
          top_k = min(self._top_k, len(pred_classes))
          pred_classes = pred_classes[:top_k]
          if pred_scores is not None:
              pred_scores = pred_scores[:top_k]
  
      example_weight = extracts.get_example_weights(
          model_name=self._model_name
      )
  
      class_weights = None
      if classes is not None and weights is not None:
          class_weights = dict(zip(classes, weights))
  
      label_classes = set(labels)
      pred_classes_scores = dict(zip(pred_classes, pred_scores))
      pred_classes = set(pred_classes)
  
      def calculate_weights(class_name):
          weight = np.array([1.0])
          if not example_weight and not class_weights:
              return None
          if example_weight:
              weight *= example_weight
          if class_weights and class_name in class_weights:
              weight *= class_weights[class_name]
          return weight
  
      # yield all true positives
      for class_name in label_classes & pred_classes:
          result = {}
          result[constants.LABELS_KEY] = np.array([1.0])
          result[constants.PREDICTIONS_KEY] = np.array(
              [pred_classes_scores[class_name]]
          )
          result[constants.EXAMPLE_WEIGHTS_KEY] = calculate_weights(
              class_name
          )
          yield metric_util.to_standard_metric_inputs(result)
  
      # yield all the false negatives
      for class_name in label_classes - pred_classes:
          result = {}
          result[constants.LABELS_KEY] = np.array([1.0])
          # set the prediction score to float('-inf') such that it will always be
          # counted as negative
          result[constants.PREDICTIONS_KEY] = np.array([float("-inf")])
          result[constants.EXAMPLE_WEIGHTS_KEY] = calculate_weights(
              class_name
          )
          yield metric_util.to_standard_metric_inputs(result)
  
      # yield all false positives
      for class_name in pred_classes - label_classes:
          result = {}
          result[constants.LABELS_KEY] = [0.0]
          result[constants.PREDICTIONS_KEY] = [
              pred_classes_scores[class_name]
          ]
          result[constants.EXAMPLE_WEIGHTS_KEY] = calculate_weights(
              class_name
          )
          yield metric_util.to_standard_metric_inputs(result)
  
file_path: model-analysis/tensorflow_model_analysis/metrics/preprocessors/set_match_preprocessors.py
imports: from typing import Iterator, Optional
  import apache_beam
  import numpy
  from tensorflow_model_analysis import constants
  from tensorflow_model_analysis.api import types
  from tensorflow_model_analysis.metrics import metric_types
  from tensorflow_model_analysis.metrics import metric_util
  from tensorflow_model_analysis.utils import util
label_desc: Use image node_id 2 for calling the SetMatchPreprocessor obj's underlying member method code with example usage: obj.process(extracts) and returns: weight, None