class_docstr: Binary classification evaluation.
  
  Evaluates the binary classification predictions in the given collection
  with respect to the specified ground truth labels.
  
  Any missing ground truth or prediction labels are assumed to be examples of
  the negative class (with zero confidence, for predictions).
  
  If an ``eval_key`` is specified, this method will record the TP/FP/FN/TN
  status of each prediction in this field.
  
  This method requires that the ``(neg_label, pos_label)`` label strings for
  the task are provided via the ``classes`` argument.
  
  Args:
      config: a :class:`BinaryEvaluationConfig`
class_docstr_tok: ["Binary","classification","evaluation",".","Evaluates","the","binary","classification","predictions","in","the","given","collection","with","respect","to","the","specified","ground","truth","labels",".","Any","missing","ground","truth","or","prediction","labels","are","assumed","to","be","examples","of","the","negative","class","(","with","zero","confidence",",","for","predictions",")",".","If","an","``","eval_key","``","is","specified",",","this","method","will","record","the","TP\/FP\/FN\/TN","status","of","each","prediction","in","this","field",".","This","method","requires","that","the","``","(","neg_label",",","pos_label",")","``","label","strings","for","the","task","are","provided","via","the","``","classes","``","argument",".","Args",":","config",":","a",":","class",":","`","BinaryEvaluationConfig","`"]
code: def evaluate_samples(
      self, samples, eval_key=None, classes=None, missing=None
  ):
      if classes is None or len(classes) != 2:
          raise ValueError(
              "You must provide the ``(neg_label, pos_label)`` labels for "
              "your task via the ``classes`` argument in order to run "
              "binary evaluation"
          )
  
      pred_field = self.config.pred_field
      gt_field = self.config.gt_field
      is_frame_field = samples._is_frame_field(gt_field)
  
      neg_label, pos_label = classes
  
      gt = gt_field + ".label"
      gt_id = gt_field + ".id"
      pred = pred_field + ".label"
      pred_id = pred_field + ".id"
      pred_conf = pred_field + ".confidence"
  
      ytrue, ytrue_ids, ypred, ypred_ids, confs = samples.values(
          [gt, gt_id, pred, pred_id, pred_conf]
      )
  
      if is_frame_field:
          ytrue = list(itertools.chain.from_iterable(ytrue))
          ytrue_ids = list(itertools.chain.from_iterable(ytrue_ids))
          ypred = list(itertools.chain.from_iterable(ypred))
          ypred_ids = list(itertools.chain.from_iterable(ypred_ids))
          confs = list(itertools.chain.from_iterable(confs))
  
      results = BinaryClassificationResults(
          samples,
          self.config,
          eval_key,
          ytrue,
          ypred,
          confs,
          classes,
          ytrue_ids=ytrue_ids,
          ypred_ids=ypred_ids,
          backend=self,
      )
  
      if eval_key is None:
          return results
  
      if is_frame_field:
          eval_frame = samples._FRAMES_PREFIX + eval_key
          gt = gt[len(samples._FRAMES_PREFIX) :]
          pred = pred[len(samples._FRAMES_PREFIX) :]
  
          Fgt = (F(gt) != None).if_else(F(gt), neg_label)
          Fpred = (F(pred) != None).if_else(F(pred), neg_label)
  
          # Sample-level accuracies
          samples.set_field(
              eval_key,
              F("frames").map((Fgt == Fpred).to_double()).mean(),
          ).save(eval_key)
  
          # Per-frame accuracies
          # This implementation implicitly treats missing data as `neg_label`
          samples.set_field(
              eval_frame,
              F().switch(
                  {
                      (F(gt) == pos_label)
                      & (F(pred) == pos_label): "TP",
                      (F(gt) == pos_label)
                      & (F(pred) != pos_label): "FN",
                      (F(gt) != pos_label)
                      & (F(pred) != pos_label): "TN",
                      (F(gt) != pos_label)
                      & (F(pred) == pos_label): "FP",
                  }
              ),
          ).save(eval_frame)
      else:
          # Per-sample accuracies
          # This implementation implicitly treats missing data as `neg_label`
          samples.set_field(
              eval_key,
              F().switch(
                  {
                      (F(gt) == pos_label)
                      & (F(pred) == pos_label): "TP",
                      (F(gt) == pos_label)
                      & (F(pred) != pos_label): "FN",
                      (F(gt) != pos_label)
                      & (F(pred) != pos_label): "TN",
                      (F(gt) != pos_label)
                      & (F(pred) == pos_label): "FP",
                  }
              ),
          ).save(eval_key)
  
      return results
  
imports: from copy import deepcopy
  import inspect
  import itertools
  import warnings
  import numpy
  import sklearn.metrics
  import eta.core.utils
  import fiftyone
  import fiftyone.core.evaluation
  from fiftyone.core.expressions import ViewField
  import fiftyone.core.fields
  import fiftyone.core.labels
  import fiftyone.core.plots
  import fiftyone.core.utils
  import fiftyone.core.validation
  from .base import BaseEvaluationResults
label_desc: Use image node_id 2 for calling the BinaryEvaluation obj's underlying member method code with example usage: obj.evaluate_samples(samples, eval_key, classes, missing) and returns: results, results