class_docstr: The F1 metric based on entity-level.
  
  We follow the convention of `CoNLL 2003 <https://aclanthology.org/W03-0419/>`_, where:
  `"precision is the percentage of named entities found by the learning system that are correct.
  Recall is the percentage of named entities present in the corpus that are found by the system.
  A named entity is correct only if it is an exact match (...).”`
class_docstr_tok: ["The","F1","metric","based","on","entity-level",".","We","follow","the","convention","of","`","CoNLL","2003","<","https",":","\/\/aclanthology.org\/W03-0419\/",">","`","_",",","where",":","`","``","precision","is","the","percentage","of","named","entities","found","by","the","learning","system","that","are","correct",".","Recall","is","the","percentage","of","named","entities","present","in","the","corpus","that","are","found","by","the","system",".","A","named","entity","is","correct","only","if","it","is","an","exact","match","(","...",")",".","\u201d","`"]
code: def apply(
      self, records: Iterable[ServiceTokenClassificationRecord]
  ) -> Dict[str, Any]:
      # store entities per label in dicts
      predicted_entities = {}
      annotated_entities = {}
  
      # extract entities per label to dicts
      for rec in records:
          if rec.prediction:
              self._add_entities_to_dict(
                  rec.prediction.entities, predicted_entities
              )
          if rec.annotation:
              self._add_entities_to_dict(
                  rec.annotation.entities, annotated_entities
              )
  
      # store precision, recall, and f1 per label
      per_label_metrics = {}
  
      annotated_total, predicted_total, correct_total = 0, 0, 0
      precision_macro, recall_macro = 0, 0
      for label, annotated in annotated_entities.items():
          predicted = predicted_entities.get(label, set())
          correct = len(annotated & predicted)
  
          # safe divides are used to cover the 0/0 cases
          precision = self._safe_divide(correct, len(predicted))
          recall = self._safe_divide(correct, len(annotated))
          per_label_metrics.update(
              {
                  f"{label}_precision": precision,
                  f"{label}_recall": recall,
                  f"{label}_f1": self._safe_divide(
                      2 * precision * recall, precision + recall
                  ),
              }
          )
  
          annotated_total += len(annotated)
          predicted_total += len(predicted)
          correct_total += correct
  
          precision_macro += precision / len(annotated_entities)
          recall_macro += recall / len(annotated_entities)
  
      # store macro and micro averaged precision, recall and f1
      averaged_metrics = {
          "precision_macro": precision_macro,
          "recall_macro": recall_macro,
          "f1_macro": self._safe_divide(
              2 * precision_macro * recall_macro,
              precision_macro + recall_macro,
          ),
      }
  
      precision_micro = self._safe_divide(
          correct_total, predicted_total
      )
      recall_micro = self._safe_divide(correct_total, annotated_total)
      averaged_metrics.update(
          {
              "precision_micro": precision_micro,
              "recall_micro": recall_micro,
              "f1_micro": self._safe_divide(
                  2 * precision_micro * recall_micro,
                  precision_micro + recall_micro,
              ),
          }
      )
  
      return {**averaged_metrics, **per_label_metrics}
  
imports: from typing import Any, ClassVar, Dict, Iterable, List, Optional, Set, Tuple
  from argilla.server.pydantic_v1 import BaseModel, Field
  from argilla.server.services.metrics import ServiceBaseMetric, ServicePythonMetric
  from argilla.server.services.metrics.models import CommonTasksMetrics
  from argilla.server.services.search.model import ServiceRecordsQuery
  from argilla.server.services.tasks.token_classification.model import EntitySpan, ServiceTokenClassificationAnnotation, ServiceTokenClassificationRecord
  from argilla.utils import SpanUtils
label_desc: Use image node_id 1 for calling the F1Metric obj's underlying member method code with example usage: obj.apply(records) and returns: dict