How do you calculate per-class precision, recall, and F1-score in multiclass classification?
Per-class metrics evaluate each label separately by temporarily treating that label as the positive class and every other label as “not that class.” This is called one-vs-rest evaluation; it does not require retraining the classifier.
Step-by-step numerical example
Suppose a model classifies 12 photos as Cat, Dog, or Bird. Read each line as actual label → predicted counts:
- Actual Cat (5): Cat 4, Dog 1, Bird 0.
- Actual Dog (4): Cat 1, Dog 2, Bird 1.
- Actual Bird (3): Cat 0, Dog 1, Bird 2.
Let's calculate the scores for Dog:
- TP = 2: two actual dogs were predicted as Dog.
- FP = 2: one cat and one bird were incorrectly predicted as Dog.
- FN = 2: one dog was predicted as Cat and another as Bird.
- TN = 6: remaining photos were neither actual Dog nor predicted Dog. TN is useful for the one-vs-rest view but is not needed in these three formulas.
- Dog precision = TP / (TP + FP) = 2 / 4 = 50%.
- Dog recall = TP / (TP + FN) = 2 / 4 = 50%.
- Dog F1 = 2 × precision × recall / (precision + recall) = 50%.
Now repeat the same calculation, changing only which label counts as positive:
- Cat: TP 4, FP 1, FN 1 → precision 80%, recall 80%, F1 80%.
- Bird: TP 2, FP 1, FN 1 → precision 66.7%, recall 66.7%, F1 66.7%.
Python example
PYTHONfrom sklearn.metrics import precision_recall_fscore_support y_true = ['Cat']*5 + ['Dog']*4 + ['Bird']*3 y_pred = ['Cat']*4 + ['Dog'] + ['Cat','Dog','Dog','Bird'] + ['Dog','Bird','Bird'] labels = ['Cat', 'Dog', 'Bird'] precision, recall, f1, support = precision_recall_fscore_support( y_true, y_pred, labels=labels, average=None, zero_division=0 ) for label, p, r, f, n in zip(labels, precision, recall, f1, support): print(label, round(p, 3), round(r, 3), round(f, 3), n)
Interpretation
- Dog's 50% precision means half of Dog predictions are correct; its 50% recall means half of real dogs are found.
- Per-class scores reveal exactly where errors occur; a single aggregate number can obscure that.
- For zero predicted examples, precision is undefined; for zero actual examples, recall is undefined. In this example the code explicitly uses
zero_division=0so such scores are reported as zero. Inspect support before drawing conclusions.
Key takeaway: In multiclass evaluation, pick a class, count TP/FP/FN against all other classes, calculate its three scores, and repeat for every label.
Reference: scikit-learn: precision_recall_fscore_support.
Sources & Research References
Learning Sequence
Machine Learning Curriculum
How do you evaluate a multiclass classifier when classes are imbalanced?
Explore Related Questions
Deepen your understanding across related Machine Learning topics.