The F-Score and Precision-Recall Trade-off
The source makes the point that precision and recall are separate questions, using rows from the digit classifier's report.
Why One Accuracy Number Can Mislead
A common first instinct, when a classifier scores well, is to treat the accuracy number as a verdict. If a model is correct on most of its test examples, it seems reasonable to conclude that it works. In a binary problem that conclusion is at least easy to check, because there are only two outcomes to keep track of. Multiclass problems are different. When there are ten or more possible labels, a single fraction hides which labels the model handles well and which ones it struggles with.
Multiclass accuracy is defined the same way as before: it is the fraction of correctly classified examples. The problem appears when the classes are imbalanced. Imagine a three-class problem in which 85% of the points belong to class A, 10% belong to class B, and 5% belong to class C. Consider a model that has learned nothing useful and simply predicts class A for every point. Work through the consequences before reading on.
What do you think happens?
The model predicts class A for all 100 points. What is its accuracy, and what is its recall for class B?
Reveal answer
Accuracy is 85% and recall for class B is 0%.
Exactly 85 of the 100 points are class A, so always predicting A is correct 85 times, giving 85% accuracy. Class B has 10 true members and none are found, so recall for B is 0. The same happens for class C. A headline accuracy of 85% therefore says nothing about whether the model finds the minority classes at all.
The lesson is not that accuracy is always worthless. It is that an accuracy value must be read alongside information about how the errors are distributed across classes. The tools in the rest of this article supply that information: the confusion matrix, the per-class precision, recall, and f-score, and the ways those per-class values are averaged into one number.
Reading the Confusion Matrix Grid
A confusion matrix places true labels in rows and predicted labels in columns. Each cell counts how many examples with a given true label received a given predicted label. The diagonal, where row and column match, holds the correct predictions. Every off-diagonal cell is a confusion: a true class being predicted as some other class. Reading the grid row by row tells you where each true class's examples went.
The grid below is a small generated example with 100 points, matching the 85, 10, and 5 class sizes from the imbalance example. Row A holds 85 true A points, row B holds 10, and row C holds 5. Read the nonzero off-diagonal cells: they are the confusions.
Read the grid this way. Row B has 10 true members, of which 5 are correct, 3 were predicted as A, and 2 were predicted as C. Column A, by contrast, collects 87 predictions, most of them correct, but also picks up one true C point and three true B points. The grid shows which class pairs are confused, and in which direction, something no single accuracy number reports.
The source applies this reading to a real task: classifying the ten handwritten digits in the digits dataset. A logistic regression model is trained on part of the data, predicts labels for the held-out test set, and then has its accuracy and confusion matrix printed. The reported accuracy is 95.3%, which the source describes as a sign that the model is doing pretty well. The matrix is where the more detailed story begins, and the source also shows the same counts as a colored heatmap with predicted labels on the horizontal axis, true labels on the vertical axis, and digit names as ticks. The heatmap is only a visual version of the grid, so learning to read the raw numbers first is worthwhile.
Per-Class Precision and Recall
A confusion matrix is detailed but dense. Per-class precision and recall condense it into two numbers for each class, computed by treating that class as the positive class and every other class as negative. Precision asks whether a prediction of a given class can be trusted. Recall asks whether every true member of that class was found.
Here TP is the count of true positives for class c, FP is the count of examples predicted as c that belong to another class, and FN is the count of examples of class c that were predicted as something else. In the grid, the diagonal cell for class c supplies TP, the rest of its column supplies FP, and the rest of its row supplies FN.
Precision and recall for class B
Using the generated 100-point grid, compute precision and recall for class B treated as the positive class.
- 1Find TP
The diagonal cell for B holds 5 true B points predicted as B, so TP is 5.
- 2Find FP
Column B totals 8 predictions. Subtracting the 5 correct ones leaves 3 false positives: 2 from true A and 1 from true C.
- 3Find FN
Row B totals 10 true members. Subtracting the 5 correct ones leaves 5 false negatives: 3 predicted A and 2 predicted C.
- 4Compute precision
Precision is $\frac{5}{5+3} = 0.625$. Of the 8 predictions labeled B, 5 can be trusted.
- 5Compute recall
Recall is $\frac{5}{5+5} = 0.5$. Of the 10 real B points, only half were found.
Class B has precision 0.625 and recall 0.5. Its precision is higher than its recall, so the model is more reliable when it says B than it is at finding every B.
The source makes the point that precision and recall are separate questions, using rows from the digit classifier's report. Class 0 has precision and recall both equal to 1, because no confusions involve that class. Class 7 has precision 1, meaning no other digit was mistakenly predicted as 7, yet its recall is lower at 0.94, meaning a few true 7s were missed. Class 6 has recall 1, because no digit 6 was missed, even though its precision is not perfect. A model can therefore be trustworthy in one direction and incomplete in the other.
Reading a Classification Report
A classification report condenses the confusion matrix into one row per class, with precision, recall, and f-score for each, and usually a support count showing how many true examples that class has. The source computes it with the classification_report function. The code below sets up the digits task so the report can be produced. The imports use the standard scikit-learn locations for each function involved.
load_digitssupplies the ten handwritten digit classesy_predholds the predicted label for every held-out test exampleclassification_reportprints one row per digit with precision, recall, f1-score, and support
Read the report one row at a time. Each row answers three questions for one class: how often a prediction of that class was right (precision), how often that class was found (recall), and the single balanced score combining them (f-score). The support column tells you how many true examples of that class were in the test set, which is the context needed to judge how much each row should matter.
The per-class rows are also where the model's trouble spots appear. In the digit report, class 8 has the lowest f-score at 0.91, which makes it the first row to inspect when the overall score needs explaining. The source also flags class 3 as a problem row, because its precision is lower than most of the others. These are the rows to examine before trusting the headline 95.3% accuracy.
Macro, Weighted, and Micro Averages
For imbalanced multiclass data, the source describes the most commonly used metric as the multiclass version of the f-score. The method is to compute one binary f-score per class, treating that class as positive and all other classes together as negative. That produces one f-score for each class, and a final single number is obtained by combining those per-class values in one of three ways.
The source computes the micro and macro averages on the same test predictions using the f1_score function with its average argument set to each strategy. The source's version of that line was incomplete, so the corrected form is shown below.
- average='micro' pools the counts of all classes before computing one f-score
- average='macro' takes the unweighted mean of the per-class f-scores
- average='weighted' takes the mean of per-class f-scores weighted by each class's support
Computing all three averages on the generated grid
Using the 100-point grid from earlier, with class sizes 85 for A, 10 for B, and 5 for C, compute the macro, weighted, and micro averages of the f-score.
- 1Per-class f-scores
Class A has precision 83/87 and recall 83/85, giving F1 of about 0.965. Class B has F1 of about 0.556. Class C has precision 0.6 and recall 0.6, giving F1 of 0.6.
- 2Macro average
Take the unweighted mean: $\frac{0.965 + 0.556 + 0.600}{3} \approx 0.707$. Class C counts as much as class A.
- 3Weighted average
Weight each F1 by its support: $\frac{85(0.965) + 10(0.556) + 5(0.600)}{100} \approx 0.906$. The large class dominates.
- 4Micro average
Pool the counts: TP is 83 + 5 + 3 = 91, FP is 4 + 3 + 2 = 9, FN is 2 + 5 + 2 = 9. Then precision and recall both equal $\frac{91}{100} = 0.91$, so micro F1 is 0.91.
- 5Compare
The macro value is pulled down by the weak minority class B, while the micro value treats every sample equally and so stays close to the overall accuracy.
Macro 0.707, weighted 0.906, micro 0.91. The same confusion matrix yields three different headline numbers, and the difference comes entirely from how classes or samples are weighted.
| Averaging method | How it combines classes | What it emphasizes | Result on the generated grid |
|---|---|---|---|
| Macro | Unweighted mean of per-class f-scores | Each class matters equally | 0.707 |
| Weighted | Mean of per-class f-scores weighted by support | Larger classes count more | 0.906 |
| Micro | Pooled TP, FP, and FN across all classes | Each sample matters equally | 0.91 |
Three ways to average the f-score across classes
Choosing an Average for Your Problem
The source gives a direct rule for choosing between the two most common options. If each sample matters equally, the source recommends the micro average f1-score. If each class matters equally, it recommends the macro average f1-score. The choice is about what the application is trying to protect, not about which number happens to be higher.
Apply the rule to the generated grid. If the business cares most about the common case and every individual prediction counts equally, micro's 0.91 is the relevant figure. If the rare classes matter as much as the common one, for example because missing class C is costly regardless of its size, macro's 0.707 reveals the weakness that micro hides.
Common mistake Treating a high accuracy as proof that every class is handled well
What it looks likeA model that always predicts the majority class on the 85/10/5 dataset still reports 85% accuracy.
Why it failsAccuracy pools all samples together, so a large class can hide complete failure on small classes.
Do this insteadCheck the confusion matrix and the per-class report before trusting the headline number.
Common mistake Reading precision and recall as the same thing
What it looks likeClass 7 in the digit report has precision 1 but recall 0.94.
Why it failsPrecision concerns the trustworthiness of predictions of a class, while recall concerns whether all true members were found.
Do this insteadRead the two columns separately and identify which kind of error each row shows.
Common mistake Choosing the average that gives the larger number
What it looks likeMicro gave 0.91 and macro gave 0.707 on the same predictions, so picking micro because it looks better.
Why it failsThe source ties the choice to what each sample or class is worth in the application, not to the score.
Do this insteadDecide first whether each sample or each class matters more, then pick micro or macro accordingly.
Common mistake Reading the grid's rows and columns backward, so that a true class is mistaken for a predicted class
Practice: Recall for Class C
Using the generated 100-point grid (row C: 1 predicted A, 1 predicted B, 3 predicted C; column C: 2 predictions from true B and A combined with C's own 3 correct), find the recall for class C and name the true classes whose C samples were missed.
Hints
- Recall for a class is TP divided by the row total of that class, since FN plus TP equals the true count.
- Class C has 5 true members, and 3 of them are on the diagonal.
- The off-diagonal cells in row C show where the missed C samples went.
Key Takeaways
- Accuracy is the fraction of correctly classified examples, but on imbalanced multiclass data it can hide classes that are almost never found, so the confusion matrix and per-class report must be checked alongside it.
- In the confusion matrix, true labels are rows and predicted labels are columns, and off-diagonal cells are the confusions between classes.
- Per-class precision asks whether predictions of a class can be trusted, and recall asks whether every true member of that class was found; the classification report gives both with an f-score and support for each class.
- Macro averages weight each class equally, weighted averages weight by support, and micro averages pool all counts so each sample matters equally; the source recommends micro when each sample matters equally and macro when each class matters equally.