code: def precision_recall_f1(
      y_true,
      y_pred,
      print_results=True,
      short_report=False,
      entity_of_interest=None,
  ):
      # Find all tags
      tags = set()
      for tag in itertools.chain(y_true, y_pred):
          if tag != "O":
              current_tag = tag[2:]
              tags.add(current_tag)
      tags = sorted(list(tags))
  
      results = OrderedDict()
      for tag in tags:
          results[tag] = OrderedDict()
      results["__total__"] = OrderedDict()
      n_tokens = len(y_true)
      total_correct = 0
      # Firstly we find all chunks in the ground truth and prediction
      # For each chunk we write starting and ending indices
  
      for tag in tags:
          count = 0
          true_chunk = []
          pred_chunk = []
          y_true = [str(y) for y in y_true]
          y_pred = [str(y) for y in y_pred]
          prev_tag_true = "O"
          prev_tag_pred = "O"
          while count < n_tokens:
              yt = y_true[count]
              yp = y_pred[count]
  
              create_chunk_true, pop_out_true = chunk_finder(
                  yt, prev_tag_true, tag
              )
              if pop_out_true:
                  true_chunk[-1] = (true_chunk[-1], count - 1)
              if create_chunk_true:
                  true_chunk.append(count)
  
              create_chunk_pred, pop_out_pred = chunk_finder(
                  yp, prev_tag_pred, tag
              )
              if pop_out_pred:
                  pred_chunk[-1] = (pred_chunk[-1], count - 1)
              if create_chunk_pred:
                  pred_chunk.append(count)
              prev_tag_true = yt
              prev_tag_pred = yp
              count += 1
  
          if len(true_chunk) > 0 and not isinstance(
              true_chunk[-1], tuple
          ):
              true_chunk[-1] = (true_chunk[-1], count - 1)
          if len(pred_chunk) > 0 and not isinstance(
              pred_chunk[-1], tuple
          ):
              pred_chunk[-1] = (pred_chunk[-1], count - 1)
  
          # Then we find all correctly classified intervals
          # True positive results
          tp = len(set(pred_chunk).intersection(set(true_chunk)))
          # And then just calculate errors of the first and second kind
          # False negative
          fn = len(true_chunk) - tp
          # False positive
          fp = len(pred_chunk) - tp
          if tp + fp > 0:
              precision = tp / (tp + fp) * 100
          else:
              precision = 0
          if tp + fn > 0:
              recall = tp / (tp + fn) * 100
          else:
              recall = 0
          if precision + recall > 0:
              f1 = 2 * precision * recall / (precision + recall)
          else:
              f1 = 0
          results[tag]["precision"] = precision
          results[tag]["recall"] = recall
          results[tag]["f1"] = f1
          results[tag]["n_pred"] = len(pred_chunk)
          results[tag]["n_true"] = len(true_chunk)
          results[tag]["tp"] = tp
          results[tag]["fn"] = fn
          results[tag]["fp"] = fp
  
      (
          results["__total__"],
          accuracy,
          total_true_entities,
          total_predicted_entities,
          accuracy,
      ) = _global_stats_f1(results)
      results["__total__"]["n_pred"] = total_predicted_entities
      results["__total__"]["n_true"] = total_true_entities
  
      if print_results:
          s = (
              "processed {len} tokens "
              "with {tot_true} phrases; "
              "found: {tot_pred} phrases;"
              " correct: {tot_cor}.\n\n".format(
                  len=n_tokens,
                  tot_true=total_true_entities,
                  tot_pred=total_predicted_entities,
                  tot_cor=total_correct,
              )
          )
  
          s += (
              "precision:  {tot_prec:.2f}%; "
              "recall:  {tot_recall:.2f}%; "
              "FB1:  {tot_f1:.2f}\n\n".format(
                  acc=accuracy,
                  tot_prec=results["__total__"]["precision"],
                  tot_recall=results["__total__"]["recall"],
                  tot_f1=results["__total__"]["f1"],
              )
          )
  
          if not short_report:
              for tag in tags:
                  if entity_of_interest is not None:
                      if entity_of_interest in tag:
                          s += (
                              "\t"
                              + tag
                              + ": precision:  {tot_prec:.2f}%; "
                              "recall:  {tot_recall:.2f}%; "
                              "F1:  {tot_f1:.2f} "
                              "{tot_predicted}\n\n".format(
                                  tot_prec=results[tag]["precision"],
                                  tot_recall=results[tag]["recall"],
                                  tot_f1=results[tag]["f1"],
                                  tot_predicted=results[tag]["n_pred"],
                              )
                          )
                  elif tag != "__total__":
                      s += (
                          "\t" + tag + ": precision:  {tot_prec:.2f}%; "
                          "recall:  {tot_recall:.2f}%; "
                          "F1:  {tot_f1:.2f} "
                          "{tot_predicted}\n\n".format(
                              tot_prec=results[tag]["precision"],
                              tot_recall=results[tag]["recall"],
                              tot_f1=results[tag]["f1"],
                              tot_predicted=results[tag]["n_pred"],
                          )
                      )
          elif entity_of_interest is not None:
              s += (
                  "\t"
                  + entity_of_interest
                  + ": precision:  {tot_prec:.2f}%; "
                  "recall:  {tot_recall:.2f}%; "
                  "F1:  {tot_f1:.2f} "
                  "{tot_predicted}\n\n".format(
                      tot_prec=results[entity_of_interest]["precision"],
                      tot_recall=results[entity_of_interest]["recall"],
                      tot_f1=results[entity_of_interest]["f1"],
                      tot_predicted=results[entity_of_interest][
                          "n_pred"
                      ],
                  )
              )
          log.debug(s)
      return results
  
file_path: DeepPavlov/deeppavlov/metrics/fmeasure.py
imports: import itertools
  from collections import OrderedDict
  from itertools import chain
  from logging import getLogger
  import numpy
  from sklearn.metrics import f1_score
  from deeppavlov.core.common.metrics_registry import register_metric
label_desc: Use image node_id 9 for calling a global function with example usage: precision_recall_f1(y_true, y_pred, print_results, short_report, entity_of_interest) and returns: results