code: def score_by_entity(
      pred_tag_sequences,
      gold_tag_sequences,
      verbose=True,
      ignore_tags=None,
  ):
      """Score predicted tags at the entity level.
  
      Args:
          pred_tags_sequences: a list of list of predicted tags for each word
          gold_tags_sequences: a list of list of gold tags for each word
          verbose: print log with results
          ignore_tags: a list or a string with a comma-separated list of tags to ignore
  
      Returns:
          Precision, recall and F1 scores.
      """
      assert len(gold_tag_sequences) == len(
          pred_tag_sequences
      ), "Number of predicted tag sequences does not match gold sequences."
  
      def decode_all(tag_sequences):
          # decode from all sequences, each sequence with a unique id
          ents = []
          for sent_id, tags in enumerate(tag_sequences):
              for ent in decode_from_bioes(tags):
                  ent["sent_id"] = sent_id
                  ents += [ent]
          return ents
  
      ignore_tag_set = set()
      if ignore_tags:
          if isinstance(ignore_tags, str):
              ignore_tag_set.update(ignore_tags.split(","))
          else:
              ignore_tag_set.update(ignore_tags)
  
      gold_ents = decode_all(gold_tag_sequences)
      gold_ents = [
          x for x in gold_ents if x["type"] not in ignore_tag_set
      ]
  
      pred_ents = decode_all(pred_tag_sequences)
      pred_ents = [
          x for x in pred_ents if x["type"] not in ignore_tag_set
      ]
  
      # scoring
      true_positive_by_type = Counter()
      false_positive_by_type = Counter()
      false_negative_by_type = Counter()
      guessed_by_type = Counter()
      gold_by_type = Counter()
  
      for p in pred_ents:
          guessed_by_type[p["type"]] += 1
          if p in gold_ents:
              true_positive_by_type[p["type"]] += 1
          else:
              false_positive_by_type[p["type"]] += 1
      for g in gold_ents:
          gold_by_type[g["type"]] += 1
          if g not in pred_ents:
              false_negative_by_type[g["type"]] += 1
  
      entities = sorted(
          set(
              list(true_positive_by_type.keys())
              + list(false_positive_by_type.keys())
              + list(false_negative_by_type.keys())
          )
      )
      entity_f1 = {}
      for entity in entities:
          entity_f1[entity] = (
              2
              * true_positive_by_type[entity]
              / (
                  2 * true_positive_by_type[entity]
                  + false_positive_by_type[entity]
                  + false_negative_by_type[entity]
              )
          )
  
      prec_micro = 0.0
      if sum(guessed_by_type.values()) > 0:
          prec_micro = (
              sum(true_positive_by_type.values())
              * 1.0
              / sum(guessed_by_type.values())
          )
      rec_micro = 0.0
      if sum(gold_by_type.values()) > 0:
          rec_micro = (
              sum(true_positive_by_type.values())
              * 1.0
              / sum(gold_by_type.values())
          )
      f_micro = 0.0
      if prec_micro + rec_micro > 0:
          f_micro = (
              2.0 * prec_micro * rec_micro / (prec_micro + rec_micro)
          )
  
      if verbose:
          logger.info(
              "Score by entity:\nPrec.\tRec.\tF1\n{:.2f}\t{:.2f}\t{:.2f}".format(
                  prec_micro * 100, rec_micro * 100, f_micro * 100
              )
          )
      return prec_micro, rec_micro, f_micro, entity_f1
  
imports: import sys
  import os
  import logging
  from collections import Counter, defaultdict
  from stanza.models.ner.utils import decode_from_bioes
label_desc: Use image node_id 1 for calling a global function with example usage: score_by_entity(pred_tag_sequences, gold_tag_sequences, verbose, ignore_tags) and returns: prec_micro,  rec_micro,  f_micro,  entity_f1, ents