Machine Learning · Machine Learning Core
Precision and Recall
Precision and recall measure two different error costs — false alarms versus missed cases — and almost always trade off.
After the confusion matrix is clear, the next question is which error hurts more. Precision defends against false alarms; recall defends against missed cases — and a threshold move almost always trades one for the other. This lesson locks that vocabulary, then lets you compute both on an imbalanced hold-out in the browser.
- Machine Learning
- Medium level
- 5 concepts
- 10 practice questions
1Two mistakes, two report cards
Picture your email spam filter at the end of one day. It moved 10 emails into the spam folder. You go through that folder by hand and find that 8 of them really were spam — but 2 were real messages from actual people, wrongly buried. Meanwhile, 12 more spam emails slipped past the filter and are sitting in your inbox. Notice that two completely different things went wrong here: the filter made some bad calls (the 2 buried messages), and it also missed a lot of what it was supposed to catch (the 12 that got through). Precision and recall are the names for those two separate report cards.
Before the formulas, we need names for the four things that can happen to a single email. When the filter flags an email as spam, we call that a positive prediction; when it leaves the email alone, that is a negative prediction. Compare each prediction to the truth and you get four buckets: a true positive (TP) is an email the filter flagged that really was spam — a hit. A false positive (FP) is an email it flagged that was actually real mail — a false alarm. A false negative (FN) is a spam email it failed to flag — a miss. And a true negative (TN) is a normal email it correctly left alone. In our day: TP = 8, FP = 2, FN = 12.
Figure. The same day, read two ways. The spam folder holds the 10 emails the filter flagged, and 2 of them were real messages wrongly buried - bad calls. Meanwhile 20 spam emails actually arrived, and 12 slipped past into the inbox - missed catches. Precision grades the first failure; recall grades the second.
| Bucket | What happened | In our day |
|---|---|---|
| True positive (TP) | Flagged as spam, and it really was — a hit | 8 emails |
| False positive (FP) | Flagged, but it was real mail — a false alarm | 2 buried messages |
| False negative (FN) | Real spam the filter failed to flag — a miss | 12 sitting in the inbox |
| True negative (TN) | Normal email correctly left alone | the rest of the day's mail |
In an email spam filter, what does high Precision specifically ensure for the user?
- That every single spam email sent to the user is intercepted
- That the inbox storage quota is reduced by at least fifty percent
- That incoming emails are sorted strictly in chronological sequence
- That emails placed into the junk folder are almost certainly genuine spam
High precision means when the filter says 'Spam', it is rarely wrong, so legitimate messages do not get lost in the junk folder.
2Precision grades the calls you made
Precision answers one plain question: of the ones I flagged, how many were real? Look only at the spam folder — the 10 emails the filter chose to flag — and ask what fraction of those calls were correct. As a formula, precision = TP/(TP+FP). The denominator, TP+FP, is simply everything the filter flagged: the 8 hits plus the 2 false alarms, which is the whole spam folder. Here precision = 8/(8+2) = 8/10 = 0.8 — when this filter points at something and says "spam", it is right 80% of the time.
You might wonder: what about the 12 spam emails it missed? Deliberately, they appear nowhere in precision. Precision only grades the calls the filter actually made; it says nothing about what it failed to flag. A filter that flagged just one email all day — and got it right — would have a perfect precision of 1/1 = 1.0 while letting a flood of spam through. That blind spot is exactly why a second metric exists.
Precision, on the day's numbers
- Count the flagsThe denominator TP + FP is everything the filter flagged: 8 hits plus 2 false alarms, the whole 10-email spam folder.
- Divide the hitsprecision = 8/10 = 0.8, so when this filter says spam, it is right 80% of the time.
- Mind the blind spotThe 12 missed spam emails appear nowhere in precision - it grades only the calls the filter actually made.
The one-flag filter beats yours on precision
Same day of email, two filters. Your filter flagged 10 emails: 8 really were spam (TP = 8) and 2 were genuine messages wrongly buried (FP = 2). A rival 'cautious' filter flagged exactly one email all day — its single surest catch — and that one really was spam. Twenty spam emails actually arrived during the day. Compute each filter's precision, then count how many spam emails each one left sitting in the inbox, and put the two comparisons side by side.
- Cautious filter's precision — its flagged pile holds 1 email and 1 of it is spam: 1/11.0 — a perfect score
- Your filter's precision — 8 hits out of the 10-email flag pile: 8/(8+2)8/10 = 0.8
- Spam the cautious filter left in the inbox: 20 arrived, it caught 1, so 20 - 119 spam emails uncaught
- Spam your filter left in the inbox: 20 - 812 spam emails uncaught
- The difference the 'perfect' filter costs: 19 - 127 more spam emails in the inbox than yours, at higher precision
Pro tip. Precision's denominator is only the flag pile, so a filter can buy a perfect 1.0 simply by refusing to flag anything it is not certain of — the 19 uncaught spam emails appear nowhere in the score. That is not a reason to distrust precision; it is the reason precision is never quoted alone, and why its partner metric starts its count from the 20 spam that truly arrived rather than from the flags.
A model makes 20 positive predictions. 15 are true positives and 5 are false positives. What is the Precision?
- 75%, calculated as 15 / (15 + 5) = 15 / 20 = 0.75
- 33%, calculated as the ratio of false positives to true positives
- 100%, because at least fifteen true cases were successfully identified
- 25%, calculated as the error rate of false positives over total calls
Precision = TP / (TP + FP) = 15 / 20 = 75%.
3Recall starts from the truth
Recall answers the other plain question: of the real ones, how many did I catch? Now the starting point is not the spam folder but the truth: every email that really was spam, whether the filter caught it or not. As a formula, recall = TP/(TP+FN). The denominator, TP+FN, is all the genuinely-spam emails: the 8 it caught plus the 12 it missed, so 20 in total. Here recall = 8/(8+12) = 8/20 = 0.4 — the filter caught only 40% of the spam that actually arrived. Note the two formulas share the same numerator, TP, the hits; they differ only in what they divide by, and that denominator is the whole difference between the two questions.
Figure. Precision reads down the predicted-positive column: of the calls you made, what share were hits — TP over TP+FP, so false alarms drag it down. Recall reads across the actual-positive row: of the true positives, what share did you catch — TP over TP+FN, so misses drag it down. The shared numerator is the true-positive cell; the two error cells are the different costs, and a threshold move that shrinks one error cell usually grows the other.
| Question | Formula | Denominator counts | On the day |
|---|---|---|---|
| Of the ones I flagged, how many were real? | precision = TP/(TP+FP) | The 10-email spam folder: 8 hits + 2 false alarms | 8/10 = 0.8 |
| Of the real ones, how many did I catch? | recall = TP/(TP+FN) | All 20 spam that arrived: 8 caught + 12 missed | 8/20 = 0.4 |
Flag everything and score a perfect recall
Recall has a blind spot that mirrors precision's, and you can compute it. Suppose 80 emails arrived that day in total: the 20 that really were spam plus 60 genuine messages. A reckless filter flags every single email as spam — all 80 go to the spam folder. Work out that filter's recall, then its precision, and compare both numbers with your filter's pair from this day (recall 8/20 = 0.4, precision 8/10 = 0.8).
- The reckless filter's hits: all 20 real spam emails are in its flag pile, so TP = 20 and its misses are FN = 20 - 20TP = 20, FN = 0
- Its recall, catches over all real spam: 20/(20+0)1.0 — a perfect score
- But its flag pile is the entire day's mail, so the genuine messages buried with the spam number FP = 6060 real messages in the spam folder
- Its precision, hits over everything flagged: 20/(20+60)20/80 = 0.25
- Side by side — recall: reckless 1.0 against your 0.4; precision: reckless 0.25 against your 0.8each filter wins the metric its strategy games and loses the other
Pro tip. Recall's denominator — the 20 spam that truly arrived — is fixed by the world, not by the filter, so flagging more emails can only push recall up, never down. That is exactly what makes recall alone gameable: flag everything and the score is a perfect 1.0 while all 60 genuine messages drown. One metric grades the flag pile, the other grades the hunt, and only quoted together do they expose a filter that games one by wrecking the other.
"Our model catches 90% of real fraud cases." Which metric is that sentence quoting?
- Precision — it is about the model's positive calls
- Accuracy — it is a share of correct predictions
- ROC-AUC — catching cases is a ranking property
- Recall — the denominator is the actual positives, and it measures how many were caught
"Of the real fraud cases, how many did we catch" conditions on actual positives — recall. Precision would condition on the rows the model flagged.
4The threshold trades one for the other
Why can't we just push both to 100%? Because under the hood the filter gives each email a suspicion score and flags everything above a cutoff, called the threshold. Lower the threshold and the filter flags more emails: it catches more of the real spam (fewer misses, so recall goes up), but it also sweeps in more innocent mail (more false alarms, so precision goes down). Raise the threshold and the trade runs the other way. Moving the threshold almost never improves both at once — it slides you along a trade-off.
Which side of the trade you favour depends on which mistake costs more in your problem. For a spam filter, the painful error is burying a real message from a real person — a false alarm — so spam filters lean toward high precision. For a disease screening test, the painful error is telling a sick patient they are fine — a miss — so screening leans toward high recall and accepts some false alarms, because a false alarm just means one more follow-up test while a miss can cost a life.
- Precision firstOf rows you called positive, what fraction were right? High precision means few false alarms.
- Recall secondOf all actual positives, what fraction did you catch? High recall means few misses.
- Expect a trade-offLowering the threshold usually raises recall and drops precision — pick the side your decision costs favour.
| Metric | Question | Typical priority |
|---|---|---|
| Precision | Were my positive calls right? | Spam / alerts |
| Recall | Did I catch the true positives? | Screening / fraud |
Lower the cutoff, recompute both
Stay with the same day of email: 20 spam messages actually arrived, and at the current cutoff the filter flagged 10 emails — 8 real spam plus 2 genuine messages wrongly buried. You lower the cutoff, so the filter flags 6 more emails, the ones whose suspicion scores sat just below the old line. Of those 6 new flags, 4 are spam it had been missing and 2 are more genuine mail. Recompute precision and recall at the new cutoff and compare them with the old values.
- Old precision = TP/(TP+FP) = 8/(8+2)8/10 = 0.80
- Old recall = TP/(TP+FN) = 8/(8+12)8/20 = 0.40
- New TP = 8 + 412 spam caught — lowering the cutoff only adds flags, so no old hit is lost
- New FP = 2 + 24 genuine messages now buried
- New FN = 20 - 128 spam still sitting in the inbox
- New precision = 12/(12+4)12/16 = 0.75, down from 0.80
- New recall = 12/(12+8)12/20 = 0.60, up from 0.40
Pro tip. The two denominators explain the trade. Recall divides by the 20 spam that actually arrived — no cutoff can change that number, so extra flags can only lift recall. Precision divides by everything flagged, and the extra flags are the filter's least confident calls, so precision usually slips.
If you raise the probability threshold for flagging suspicious transactions from 0.3 to 0.8, what is the typical result?
- Precision increases while Recall drops, as only high-confidence alerts are triggered
- Recall increases while Precision drops across all transaction types
- Both Precision and Recall increase simultaneously to 100%
- The total number of flagged transactions increases substantially
A stricter threshold demands higher certainty to flag a case, reducing false alarms (higher precision) but letting borderline cases slip through (lower recall).
5Lab: precision and recall on an imbalanced set
In this lab you build a small classifier, keep some rows hidden from it, and then measure precision and recall on those hidden rows. The dataset is deliberately imbalanced: about 90% of the rows belong to one class and only 10% to the other. That 90/10 shape mimics real problems like fraud or disease detection, where the cases you actually care about are rare — and it is exactly the shape where precision and recall matter more than accuracy.
Cell 1 does the whole setup, so here is what each piece is. `make_classification` manufactures a fake labelled dataset for practice (the `weights=[0.9, 0.1]` argument is what makes the positive class rare). `train_test_split` sets aside 30% of the rows as a test set the model never sees during fitting — scores computed on rows the model trained on would flatter it. `LogisticRegression` is the classifier being fitted. After fitting, `y_test` holds the true labels of the held-out rows, and `pred` holds the model's guesses for those same rows. `precision_score` and `recall_score` then compare those two lists — guesses against truth — and `confusion_matrix` prints the four raw counts (hits, false alarms, misses, correct passes) behind them.
Cell 2 draws a bar chart of precision next to recall. It can do that without re-fitting anything because `y_test` and `pred` from Cell 1 are still alive in the notebook's kernel — the shared memory that survives between cells. Change the bar colours or the title and re-run only Cell 2; the model and its predictions stay put.
When the numbers print, here is the trap to look for. On a 90/10 split, a lazy model that predicts the majority class for nearly every row scores close to 90% accuracy — while catching almost none of the rare positives. Accuracy looks healthy; recall collapses toward zero. That is why this lab prints precision, recall, and the four confusion counts instead of a single accuracy number: recall is the metric that exposes the laziness.
One last framing note: the bar chart is not a contest where the taller bar wins. Precision and recall answer two different questions — "of the rows I flagged, how many were right?" and "of the real positives, how many did I catch?" — and the chart simply puts the two answers side by side so you can see where your model's errors live.
No diagram — the fit is drawn by the coding lab plot, not a static figure.
- Fit on imbalanced trainUse the 90/10 split and fit LogisticRegression on X_train, y_train only.
- Predict on testGenerate y_pred on the held-out fold — never train rows.
- Print both metricsReport precision_score and recall_score alongside the four confusion counts.
| Step | Why |
|---|---|
| Imbalanced make_classification | Rare positives make precision/recall matter more than accuracy |
| Hold out a test fold | Scores must use rows the fit never saw |
| Print precision, recall, counts | Both rates and the four cells tell the full story |
| Bar precision vs recall | Shared-kernel view of the two questions side by side |
Coding lab. Precision and recall on an imbalanced hold-out runs in the app, with checks on your output.
On the 90/10 lab split, accuracy looks fine but recall collapses. What is the model most likely doing?
- Overfitting the minority class
- Flagging almost every row as positive
- Confusing the two features with each other
- Predicting the majority class almost everywhere, so most rare positives are missed
On a 90/10 split, siding with the majority keeps accuracy near 0.9 while catching few positives — exactly the case where recall, not accuracy, tells the story.
Notes
- Precision asks: of the rows I called positive, how many were right?
- Recall asks: of the rows that truly were positive, how many did I catch?
- Lowering the threshold usually lifts recall and costs precision.
Exam traps & shortcuts
- Keep lab datasets under 2000 rows in the browser runtime.
- Split train and test before fitting any model that sees labels.
Recap
This lesson in brief:
- Precision
- Precision asks: of the rows I called positive, how many were right? High precision means few false alarms.
- Recall
- Recall asks: of the rows that truly were positive, how many did I catch? High recall means few missed cases.
- The trade-off
- You rarely get both for free: lowering the threshold catches more positives (recall up) and usually adds false alarms (precision down).
Practise Precision and Recall
Reading is free and needs no account. Practice, mocks and progress live in the app.
- 10 exam-style questions on this topic, with explanations
- A 5-question practice set that ends the chapter
- Timed mocks scored with the real marking scheme
- Readiness tracked per topic, kept on your device