class_docstr: A basic f1 computation for text classification
  
  Attributes:
  -----------
      multi_label:
          If True, F1 will be calculated assuming multi class task. Default False
class_docstr_tok: ["A","basic","f1","computation","for","text","classification","Attributes",":","--","--","--","--","--","-","multi_label",":","If","True",",","F1","will","be","calculated","assuming","multi","class","task",".","Default","False"]
code: def apply(
      self, records: Iterable[ServiceTextClassificationRecord]
  ) -> Any:
      from sklearn.metrics import precision_recall_fscore_support
  
      filtered_records = list(
          filter(lambda r: r.predicted is not None, records)
      )
      # TODO: This must be precomputed with using a global dataset metric
      ds_labels = {
          label
          for record in filtered_records
          for label in record.annotated_as + record.predicted_as
      }
  
      if not len(ds_labels):
          return {}
  
      labels_mapping = {label: i for i, label in enumerate(ds_labels)}
      y_true, y_pred = ([], [])
      for record in filtered_records:
          annotations = record.annotated_as
          predictions = record.predicted_as
  
          if not self.multi_label:
              y_true.append(labels_mapping[annotations[0]])
              y_pred.append(labels_mapping[predictions[0]])
  
          else:
              y_true.append(
                  [labels_mapping[label] for label in annotations]
              )
              y_pred.append(
                  [labels_mapping[label] for label in predictions]
              )
  
      if self.multi_label:
          from sklearn.preprocessing import MultiLabelBinarizer
  
          mlb = MultiLabelBinarizer(
              classes=list(labels_mapping.values())
          )
          y_true = mlb.fit_transform(y_true)
          y_pred = mlb.fit_transform(y_pred)
  
      micro_p, micro_r, micro_f, _ = precision_recall_fscore_support(
          y_true=y_true, y_pred=y_pred, average="micro"
      )
      macro_p, macro_r, macro_f, _ = precision_recall_fscore_support(
          y_true=y_true, y_pred=y_pred, average="macro"
      )
  
      per_label = {}
      for label, p, r, f, s in zip(
          labels_mapping.keys(),
          *precision_recall_fscore_support(
              y_true=y_true,
              y_pred=y_pred,
              average=None,
          ),
      ):
          per_label.update(
              {
                  f"{label}_precision": p.tolist(),
                  f"{label}_recall": r.tolist(),
                  f"{label}_f1": f.tolist(),
                  f"{label}_support": s.tolist(),
              }
          )
  
      return {
          "precision_macro": macro_p,
          "recall_macro": macro_r,
          "f1_macro": macro_f,
          "precision_micro": micro_p,
          "recall_micro": micro_r,
          "f1_micro": micro_f,
          **per_label,
      }
  
file_path: argilla/src/argilla/server/services/tasks/text_classification/metrics.py
imports: from typing import Any, ClassVar, Dict, Iterable, List
  from argilla.server.pydantic_v1 import 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.text_classification.model import ServiceTextClassificationRecord
  from argilla.utils.dependency import requires_dependencies
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, dict