Micro F1 Score

Micro F1 pools the counts across every class before computing anything:

\(\text{Precision}_{\text{micro}} = \dfrac{\sum TP_i}{\sum (TP_i + FP_i)}, \qquad \text{Recall}_{\text{micro}} = \dfrac{\sum TP_i}{\sum (TP_i + FN_i)}\)

and then combines them in the usual way, \(F1 = 2PR/(P+R)\). It is the counterpart to macro F1, which computes F1 within each class and averages afterward.

All three are the same number

In a single-label problem — every sample gets exactly one predicted class, and the average is taken over every class — micro precision, micro recall and micro F1 are equal, and all three equal accuracy.

import numpy as np
from sklearn.metrics import f1_score, precision_score, recall_score, accuracy_score, confusion_matrix

rng = np.random.default_rng(6)
names = ["common", "medium", "rare"]
support = dict(zip(names, (4000, 800, 120)))
hit_rate = dict(zip(names, (0.95, 0.70, 0.35)))
truth, pred = [], []
for name, n in support.items():
    truth += [name] * n
    others = [k for k in names if k != name]
    pred += [name if rng.uniform() < hit_rate[name] else rng.choice(others) for _ in range(n)]

matrix = confusion_matrix(truth, pred, labels=names)
tp = np.diag(matrix)
print(f"sum FP {int((matrix.sum(axis=0) - tp).sum())}  sum FN {int((matrix.sum(axis=1) - tp).sum())}")
kw = dict(labels=names, average="micro", zero_division=0)
print(f"micro precision {precision_score(truth, pred, **kw):.6f}")
print(f"micro recall    {recall_score(truth, pred, **kw):.6f}")
print(f"micro F1        {f1_score(truth, pred, **kw):.6f}")
print(f"accuracy        {accuracy_score(truth, pred):.6f}")

published = dict(tp=80, fp=50, fn=60)
"""Counts quoted in the published example, which cannot come from one single-label matrix."""
p = published["tp"] / (published["tp"] + published["fp"])
r = published["tp"] / (published["tp"] + published["fn"])
print(f"published counts: micro P {p:.4f}  micro R {r:.4f}  F1 {2 * p * r / (p + r):.4f}")
# sum FP 501  sum FN 501
# micro precision 0.898171
# micro recall    0.898171
# micro F1        0.898171
# accuracy        0.898171
# published counts: micro P 0.6154  micro R 0.5714  F1 0.5926

The first line is the reason. Every misclassified sample is counted once as a false positive for the class it was wrongly given and once as a false negative for the class it belonged to, so \(\sum FP = \sum FN\) exactly — 501 each here. Both micro denominators therefore equal the number of samples, the two micro values coincide, their harmonic mean is that same value, and \(\sum TP\) over the total is the definition of accuracy. 0.898171 four times over.

That is worth stating as a consequence rather than a curiosity: if accuracy was rejected for this problem because the classes are imbalanced, micro F1 does not fix anything. It is the same number wearing a name that sounds like it accounts for imbalance.

A check the identity gives you free

Because \(\sum FP = \sum FN\) is arithmetic rather than approximate, any worked example that violates it cannot have come from a single-label confusion matrix. The last line of the output takes a commonly quoted set of counts — \(\sum TP = 80\), \(\sum FP = 50\), \(\sum FN = 60\) — and produces micro precision 0.6154, micro recall 0.5714 and micro F1 0.5926: three different numbers from an example presented to illustrate that all three are equal.

There is no repair that keeps those counts. In a real matrix with 80 correct predictions and 60 misses, the false positives are also 60, and all three values are \(80/140 = 0.5714\).

Where the identity stops

  • Multilabel problems. A sample can carry several labels, so predicting too few on one sample and too many on another no longer balances the two totals. Micro precision and micro recall genuinely differ, and micro F1 becomes a real summary rather than accuracy renamed.
  • A restricted label set. Passing labels with a subset of the classes breaks the accounting: with truth [0, 1, 2], predictions [0, 0, 2] and labels=[0], micro precision is 0.5, micro recall is 1.0 and accuracy is 2/3 — see micro precision.

Outside those two cases, the useful companion is macro F1, which weights every class equally: 0.6507 against micro’s 0.8982 on the predictions above, because the rare class is detected in 49 of its 120 cases (about 41%) in this sample, while micro gives its errors less weight than errors in the common class. The pair says something; micro on its own says what accuracy already said.

References


Discover more from Insightful Data Lab

Subscribe to get the latest posts sent to your email.

Similar Posts

Questions, corrections, or additional insights?

This site uses Akismet to reduce spam. Learn how your comment data is processed.