Micro Averaging
Micro averaging pools the counts first and computes the metric once. Add up the true positives, false positives and false negatives across all classes, then divide.
\[ \text{Micro Recall} = \frac{\sum_i TP_i}{\sum_i (TP_i + FN_i)} \]
With classes A (TP 90, FP 10), B (TP 30, FP 20) and C (TP 5, FP 15), macro precision is \((0.90 + 0.60 + 0.25)/3 = 0.583\) while micro precision is \(125/170 = 0.735\). Macro lets class C’s weak score count as much as A’s; micro lets A’s volume dominate. Every sample has equal weight, not every class.
There is a consequence of that pooling which is easy to state and easy to miss.
In single-label problems it is accuracy
import numpy as np
from sklearn.metrics import accuracy_score, f1_score, precision_score, recall_score
y = np.array([0] * 700 + [1] * 250 + [2] * 50)
rng = np.random.default_rng(0)
pred = y.copy()
pred[rng.choice(np.flatnonzero(y == 0), 60, replace=False)] = 1
pred[rng.choice(np.flatnonzero(y == 1), 90, replace=False)] = 0
pred[np.flatnonzero(y == 2)] = 0
print("single-label, three classes")
print(f" accuracy {accuracy_score(y, pred):.4f}")
for name, fn in (("micro precision", precision_score), ("micro recall", recall_score), ("micro F1", f1_score)):
print(f" {name:<15} {fn(y, pred, average='micro'):.4f}")
rng2 = np.random.default_rng(1)
n, K = 4000, 5
Y = (rng2.random((n, K)) < 0.3).astype(int)
P = np.where(rng2.random((n, K)) < 0.15, 1 - Y, Y)
print("\nmulti-label, five labels, the same three numbers come apart")
print(f" subset accuracy {accuracy_score(Y, P):.4f}")
for name, fn in (("micro precision", precision_score), ("micro recall", recall_score), ("micro F1", f1_score)):
print(f" {name:<15} {fn(Y, P, average='micro'):.4f}")
# single-label, three classes
# accuracy 0.8000
# micro precision 0.8000
# micro recall 0.8000
# micro F1 0.8000
#
# multi-label, five labels, the same three numbers come apart
# subset accuracy 0.4582
# micro precision 0.7158
# micro recall 0.8583
# micro F1 0.7806
Four numbers, one value: 0.8000 throughout.
The reason is bookkeeping. When each sample gets exactly one predicted class, a prediction that is wrong contributes a false positive to the class it named and a false negative to the class it should have named. Summed over all classes, \(\sum FP = \sum FN\), so micro precision and micro recall have the same denominator and the same numerator. Their harmonic mean is that value again, and the value is the fraction of samples predicted correctly — accuracy.
So a table listing accuracy, micro precision, micro recall and micro F1 for a single-label model has one number in four columns. It is not wrong, but it reads as corroboration when it is repetition, and it takes up space that macro and per-class figures would have used.
Where it earns its keep
The second block is multi-label: five labels, each independently right or wrong per sample. Now subset accuracy is 0.4582, micro precision 0.7158, micro recall 0.8583 and micro F1 0.7806 — four different questions with four different answers.
The identity broke because \(\sum FP\) no longer equals \(\sum FN\): predicting four labels where three were right produces a false positive with no matching false negative. Micro averaging becomes informative exactly when a sample can have more than one decision attached to it — multi-label classification, object detection, entity extraction, any per-token task.
The same holds for micro AUROC, which concatenates the one-vs-rest scores across classes into a single vector and computes one curve. That treats scores from different classifiers as comparable, which requires them to be on a common scale — the caveat that also applies to One-vs-Rest, where separately fitted models produce scores that do not even sum to one.
What to report
- Single-label: accuracy plus macro, and the per-class table. Micro adds nothing to accuracy.
- Multi-label: micro and macro together, with subset accuracy if a partially correct label set is worthless to the user.
- Report macro and micro with the per-class results and supports. Their difference can reveal a consequence of aggregation, but it does not measure class disparity on its own. With two equally supported classes whose recalls are 1.0 and 0.5, macro and micro recall are both 0.75 despite the unequal performance. For pooled AUC, cross-class score scales add another source of differences.
And where the class distribution is very uneven, remember what micro is answering: performance on a typical sample, which in a dataset that is 90% one class is mostly performance on that class. That is the right question for a system whose cost scales with volume, and the wrong one for a system whose cost is concentrated in rare cases.
References
Discover more from Insightful Data Lab
Subscribe to get the latest posts sent to your email.
