code: def _compute_f1(
      self, predicted_bag: Set[str], gold_bag: Set[str]
  ) -> float:
      intersection = len(gold_bag.intersection(predicted_bag))
      if not predicted_bag:
          precision = 1.0
      else:
          precision = intersection / float(len(predicted_bag))
      if not gold_bag:
          recall = 1.0
      else:
          recall = intersection / float(len(gold_bag))
      f1 = (
          (2 * precision * recall) / (precision + recall)
          if not (precision == 0.0 and recall == 0.0)
          else 0.0
      )
      return f1
  
imports: import re
  import string
  from typing import Dict, List, Set, Tuple, Union
  import numpy
  from pytext.common.constants import Stage
  from pytext.metric_reporters.channel import Channel, ConsoleChannel, FileChannel
  from pytext.metric_reporters.metric_reporter import MetricReporter
  from pytext.metrics.squad_metrics import SquadMetrics
  from pytext.utils.data import merge_token_labels_to_slot, parse_slot_string, Slot
  from scipy.optimize import linear_sum_assignment
label_desc: Use image node_id 17 for calling the MultiSpanQAMetricReporter obj's underlying member method code with example usage: obj._compute_f1(predicted_bag, gold_bag) and returns: f1