code: def sequence_labeling_report(
      y_true: List[List[str]],
      y_pred: List[List[str]],
      digits: int = 2,
      suffix: bool = False,
      verbose: int = 1,
  ) -> Dict[str, Any]:
      """Build a text report showing the main classification metrics.
  
      Args:
          y_true: 2d array. Ground truth (correct) target values.
          y_pred: 2d array. Estimated targets as returned by a classifier.
          digits: int. Number of digits for formatting output floating point values.
          suffix:
          verbose:
      Returns:
          report: string. Text summary of the precision, recall, F1 score for each class.
  
      Examples:
          >>> from kashgari.metrics.sequence_labeling import sequence_labeling_report
          >>> y_true = [['O', 'O', 'O', 'B-MISC', 'I-MISC', 'I-MISC', 'O'], ['B-PER', 'I-PER', 'O']]
          >>> y_pred = [['O', 'O', 'B-MISC', 'I-MISC', 'I-MISC', 'I-MISC', 'O'], ['B-PER', 'I-PER', 'O']]
          >>> report = sequence_labeling_report(y_true, y_pred)
                       precision    recall  f1-score   support
          <BLANKLINE>
                 MISC       0.00      0.00      0.00         1
                  PER       1.00      1.00      1.00         1
          <BLANKLINE>
            micro avg       0.50      0.50      0.50         2
            macro avg       0.50      0.50      0.50         2
          <BLANKLINE>
      """
      true_entities = set(bulk_get_entities(y_true, suffix=suffix))
      pred_entities = set(bulk_get_entities(y_pred, suffix=suffix))
  
      name_width = 0
      d1: Dict = defaultdict(set)
      d2: Dict = defaultdict(set)
      for e in true_entities:
          d1[e[0]].add((e[1], e[2]))
          name_width = max(name_width, len(e[0]))
      for e in pred_entities:
          d2[e[0]].add((e[1], e[2]))
  
      last_line_heading = "macro avg"
      width = max(name_width, len(last_line_heading), digits)
  
      headers = ["precision", "recall", "f1-score", "support"]
      head_fmt = "\n{:>{width}s} " + " {:>9}" * len(headers)
      report = head_fmt.format("", *headers, width=width)
      report += "\n\n"
  
      row_fmt = "{:>{width}s} " + " {:>9.{digits}f}" * 3 + " {:>9}\n"
  
      report_dic: Dict[str, Any] = {"detail": {}}
  
      ps, rs, f1s, s = [], [], [], []
      for type_name, t_true_entities in d1.items():
          t_pred_entities = d2[type_name]
          nb_correct = len(t_true_entities & t_pred_entities)
          nb_pred = len(t_pred_entities)
          nb_true = len(t_true_entities)
  
          p = nb_correct / nb_pred if nb_pred > 0 else 0
          r = nb_correct / nb_true if nb_true > 0 else 0
          f1 = 2 * p * r / (p + r) if p + r > 0 else 0
  
          report += row_fmt.format(
              *[type_name, p, r, f1, nb_true],
              width=width,
              digits=digits,
          )
  
          report_dic["detail"][type_name] = {
              "precision": p,
              "recall": r,
              "f1-score": f1,
              "support": nb_true,
          }
          ps.append(p)
          rs.append(r)
          f1s.append(f1)
          s.append(nb_true)
  
      report += "\n"
  
      report_dic["precision"] = np.average(ps, weights=s)
      report_dic["recall"] = np.average(rs, weights=s)
      report_dic["f1-score"] = np.average(f1s, weights=s)
      report_dic["support"] = np.sum(s)
  
      # compute averages
      report += row_fmt.format(
          "micro avg",
          precision_score(y_true, y_pred, suffix=suffix),
          recall_score(y_true, y_pred, suffix=suffix),
          f1_score(y_true, y_pred, suffix=suffix),
          np.sum(s),
          width=width,
          digits=digits,
      )
      report += row_fmt.format(
          last_line_heading,
          np.average(ps, weights=s),
          np.average(rs, weights=s),
          np.average(f1s, weights=s),
          np.sum(s),
          width=width,
          digits=digits,
      )
      if verbose:
          print(report)
  
      return report_dic
  
file_path: Kashgari/kashgari/metrics/sequence_labeling.py
imports: from collections import defaultdict
  from typing import List, Dict, Tuple, Any
  import numpy
label_desc: Use image node_id 10 for calling a global function with example usage: sequence_labeling_report(y_true, y_pred, digits, suffix, verbose) and returns: report_dic