code: def compute_metric_at_k(
      references: List[Node],
      hypothesis: List[List[Node]],
      metric_fn: Callable[[Node, Node], bool] = lambda f1, f2: f1 == f2,
  ) -> List[float]:
      """
      Computes a boolean metric at each position in the ranked list of hypothesis,
      and returns an average for each position over all examples.
      By default metric_fn is comparing if frames are equal.
      """
      num_samples = len(references)
      # Position of the correct frame if present in the ranked list.
      pos_correct = []
      max_hyp_count = 0
      # Iterate over ranked list of hypothesis and remember what was the position
      # of the first correct frame.
      for reference, hyp_list in zip(references, hypothesis):
          correct_index = -1
          for rank, predicted_frame in enumerate(hyp_list):
              max_hyp_count = max(rank, max_hyp_count)
              if metric_fn(predicted_frame, reference):
                  correct_index = rank
                  break
          pos_correct.append(correct_index)
  
      res = [0] * max_hyp_count
      # Compute the number of correct frames per each position in the ranked list.
      for pos in pos_correct:
          if pos >= 0:
              for i in range(pos, max_hyp_count):
                  res[i] += 1
  
      return [safe_division(res_i, num_samples) for res_i in res]
  
imports: from collections import Counter, defaultdict
  from copy import deepcopy
  from typing import AbstractSet, Any, Callable, Counter, Dict, List, NamedTuple, Optional, Sequence, Tuple
  from pytext.data.data_structures.annotation import INVALID_TREE_INTENT
  from pytext.data.data_structures.node import Node, Span
  from .None import AllConfusions, Confusions, PerLabelConfusions, PRF1Metrics, PRF1Scores, safe_division
label_desc: Use image node_id 9 for calling a global function with example usage: compute_metric_at_k(references, hypothesis, metric_fn) and returns: unknown