class_docstr: Top-k classification evaluation.
  
  This method requires the ``logits`` field of each predicted object to be
  populated, and the list of class labels corresponding to these logits must
  be provided.
  
  Args:
      config: a :class:`TopKEvaluationConfig`
class_docstr_tok: ["Top-k","classification","evaluation",".","This","method","requires","the","``","logits","``","field","of","each","predicted","object","to","be","populated",",","and","the","list","of","class","labels","corresponding","to","these","logits","must","be","provided",".","Args",":","config",":","a",":","class",":","`","TopKEvaluationConfig","`"]
code: def evaluate_samples(
      self, samples, eval_key=None, classes=None, missing=None
  ):
      if classes is None:
          raise ValueError(
              "You must provide the list of classes corresponding to your "
              "logits in order to run top-k classification evaluation"
          )
  
      pred_field = self.config.pred_field
      gt_field = self.config.gt_field
      is_frame_field = samples._is_frame_field(gt_field)
      k = self.config.k
  
      # This extracts a potentially huge number of logits
      # @todo consider sample iteration for very large datasets?
      ytrue, ytrue_ids, ypred, ypred_ids, logits = samples.values(
          [
              gt_field + ".label",
              gt_field + ".id",
              pred_field + ".label",
              pred_field + ".id",
              pred_field + ".logits",
          ]
      )
  
      targets_map = {label: idx for idx, label in enumerate(classes)}
  
      if is_frame_field:
          confs = []
          correct = []
          for _ytrue, _ypred, _logits in zip(ytrue, ypred, logits):
              _confs, _correct = _evaluate_top_k(
                  _ytrue, _ypred, _logits, k, targets_map
              )
              confs.append(_confs)
              correct.append(_correct)
  
          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))
      else:
          confs, correct = _evaluate_top_k(
              ytrue, ypred, logits, k, targets_map
          )
  
      results = ClassificationResults(
          samples,
          self.config,
          eval_key,
          ytrue,
          ypred,
          confs=confs,
          ytrue_ids=ytrue_ids,
          ypred_ids=ypred_ids,
          classes=classes,
          missing=missing,
          backend=self,
      )
  
      if eval_key is None:
          return results
  
      if is_frame_field:
          eval_frame = samples._FRAMES_PREFIX + eval_key
  
          # Sample-level accuracies
          avg_accuracies = [np.mean(c) if c else None for c in correct]
          samples.set_values(eval_key, avg_accuracies)
  
          # Per-frame accuracies
          samples.set_values(eval_frame, correct)
      else:
          # Per-sample accuracies
          samples.set_values(eval_key, correct)
  
      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 TopKEvaluation obj's underlying member method code with example usage: obj.evaluate_samples(samples, eval_key, classes, missing) and returns: results, results