📏  Macro F1

Macro F1#

The unweighted mean of per-class F1 scores; exposes weak performance on rare classes.

Important

✨ AI-generated content. This page was written with the assistance of an AI language model and is provided as a learning aid. Despite careful review, it may still contain mistakes, omissions, or out-of-date information. Whether you are new to the topic, a team lead, or a senior practitioner, treat it as a starting point rather than an authoritative reference: read it critically and independently verify anything you act on (code, commands, figures, and factual claims) against official documentation and primary sources before relying on it.

What it is#

F1 is the harmonic mean of precision and recall, high only when both are high:

\[F_1 = \frac{2 \cdot \text{Precision} \cdot \text{Recall}} {\text{Precision} + \text{Recall}}.\]

For \(K\) classes, compute an F1 per class (one-vs-rest), then average them with equal weight to get macro F1:

\[F_{1,\text{macro}} = \frac{1}{K} \sum_{i=1}^{K} F_{1,i}.\]

Each class contributes the same, whatever its size — so weak performance on a rare class is fully visible.

Macro vs micro vs weighted#

  • Macro — equal weight per class; surfaces minority-class weakness.

  • Micro — pool global TP / FP / FN first, then compute F1; dominated by majority classes (and equals accuracy in single-label problems).

  • Weighted — average per-class F1 weighted by class frequency; a compromise that respects class sizes while staying per-class.

Worked example#

Three classes:

  • F1(A) = 0.80 (P=0.80, R=0.80)

  • F1(B) = 0.48 (P=0.60, R=0.40)

  • F1(C) = 0.33 (P=0.50, R=0.25)

\[F_{1,\text{macro}} = \frac{0.80 + 0.48 + 0.33}{3} = 0.54.\]

Class A is strong, but B and C pull the average down — exactly what you want when every class matters.

Pitfalls and edge cases#

  • Zero-division — if a class is never predicted, its precision is undefined; by convention its F1 is taken as 0, which (correctly) penalises ignoring that class.

  • Rare-class leverage — one small, hard class can dominate the macro average; read the per-class F1s alongside it.

In code#

from sklearn.metrics import f1_score

macro = f1_score(y_true, y_pred, average="macro")
weighted = f1_score(y_true, y_pred, average="weighted")

Theme: Classification & Averaging Metrics  ·  All terminology


Hint

Mind map — connected ideas

Micro F1 · Macro Precision · Macro Recall · Macro AUROC (Macro-Averaged AUROC)


See also

Source article Adapted (context, re-expressed) in our own words from: Macro F1 (insightful-data-lab.com).

Tags: purpose: reference topic: terminology level: intermediate