Intermediate: machine learning · Evaluating models · topic 29 of 62 · 35 min
Thresholds, ROC-AUC and imbalanced classes
Explanation
Scores, not just labels
Logistic regression, trees, boosting and neural networks all produce a score or probability first. The yes/no label only appears when you pick a threshold. Changing the threshold changes every count in the confusion matrix, so the "same model" can behave very differently. Evaluating only at 0.5 hides most of what the model can do.
The trade-off
- Lower threshold: more cases flagged → recall goes up, precision usually goes down (more false alarms).
- Higher threshold: fewer cases flagged → precision usually goes up, recall goes down (more misses).
y = [1, 1, 0, 1, 0, 0]
scores = [0.9, 0.7, 0.6, 0.4, 0.3, 0.1]
for th in [0.8, 0.5, 0.35]:
pred = [1 if s >= th else 0 for s in scores]
tp = sum(1 for t, p in zip(y, pred) if t == 1 and p == 1)
fp = sum(1 for t, p in zip(y, pred) if t == 0 and p == 1)
print(th, "precision", round(tp / (tp + fp), 2), "recall", round(tp / 3, 2))The ROC curve and AUC
The ROC (receiver operating characteristic) curve plots the true positive rate (recall) against the false positive rate (FP ÷ all real negatives) for every possible threshold. A useless model that guesses at random follows the diagonal. A good model bends towards the top-left corner.
AUC is the area under that curve, from 0.5 (random) to 1.0 (perfect). It has a friendly meaning: AUC is the probability that a randomly chosen positive example gets a higher score than a randomly chosen negative one. Because it looks at the ranking of scores, not one threshold, it is good for comparing models before you pick a threshold.
When ROC-AUC flatters: precision-recall curves
When positives are very rare (say 0.1% of payments), the false positive rate stays tiny even with many false alarms, so ROC-AUC can look excellent while precision is poor. The precision-recall (PR) curve and its summary, average precision, focus on the rare class and are often more honest for fraud, disease and defect detection.
Dealing with imbalanced classes
- Pick metrics that look at the rare class: recall, precision, F1, PR-AUC.
- Use class weights, for example class_weight="balanced" in scikit-learn, so mistakes on the rare class cost more during training.
- Resample the training set: oversample the rare class or undersample the common one. SMOTE creates synthetic rare examples by mixing neighbours. Only resample the TRAINING data, never the test set.
- Tune the threshold on validation data to meet a business target, such as "recall at least 90%".
Choosing the threshold
Put a cost on each mistake. If a missed fraud costs ₹20,000 and a false alarm costs ₹50 of call-centre time, try thresholds on validation data and pick the one with the lowest total cost. This turns a technical choice into a business decision everybody can understand.
Common mistakes
- Reporting only ROC-AUC for a very rare class. Fix: add precision-recall numbers.
- Choosing the threshold on the test set. Fix: choose it on validation data, then confirm once on test.
- Balancing the test set by resampling. The test set must look like the real world.
Need help?
Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.
Try:
Watch the lesson
Thresholds, ROC-AUC and imbalanced classes · 1/7
A classifier gives scores. The threshold turns scores into yes or no.
Prefer a video by a teacher? Find free videos on “ROC curve AUC explained precision recall curve imbalanced data” on YouTube ↗
In real life: Setting a fraud threshold by cost
A card issuer's fraud team plots, for each threshold on validation data, how many frauds are caught and how many genuine customers are disturbed. Using the cost of a missed fraud and the cost of a call to a customer, they pick the threshold with the lowest total cost, then add a stricter threshold for high-value transactions. The model did not change; only the decision rule did, and losses fell.
Practice (0/2 done)
Write pr_at(y_true, scores, threshold) that predicts 1 when score ≥ threshold and returns (precision, recall) rounded to 4 decimal places. Use 0.0 when a denominator is 0.
Write auc(y_true, scores) using the ranking meaning of AUC: look at every pair of (positive, negative) examples; count 1 when the positive has the higher score and 0.5 when the scores are equal. Return the count divided by the number of pairs, rounded to 4 decimal places. If there are no positives or no negatives, return None.
Quick quiz
Read more (free)
Related help
Before this, learn
This topic builds on these. If something here feels new, open them first.
Related topics
- Regression metrics: MAE, MSE, RMSE and R²Evaluating models · same module
- Train, validation and test setsEvaluating models · same module
- Evaluating LLM appsBuilding with generative AI, and MLOps
- The normal distribution and z-scoresStatistics made simple
- Choosing and explaining a modelk-NN, decision trees and ensembles
Questions people ask about this
Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.
You lower the classification threshold from 0.5 to 0.2. What usually happens?
Answer: Recall goes up and precision goes down
More cases are flagged: more caught, but more false alarms.
An AUC of 0.5 means…
Answer: No better than random ranking
At 0.5, a random positive is no more likely than a random negative to score higher.
Which statement about AUC is true?
Answer: It measures how well scores rank positives above negatives, across all thresholds
AUC is threshold-free; it is about ranking.
Fraud is 0.1% of transactions. Which is the most honest extra check besides ROC-AUC?
Answer: A precision-recall curve or average precision
PR metrics focus on the rare class and expose many false alarms.
When you oversample the rare class with SMOTE, which data should you resample?
Answer: Only the training data
The test set must reflect the real world; resampling before splitting also leaks.
Precision is 1.0 and recall is 0.1. What is F1, roughly?Related
Answer: 0.18
2 × 1 × 0.1 ÷ 1.1 ≈ 0.18. F1 stays low unless both are high.
A hospital wants to miss as few sick patients as possible. Compared with 0.5, the threshold should usually be…Related
Answer: Lower
A lower threshold flags more people, catching more true cases at the cost of more false alarms.
A RAG bot gives wrong answers. recall@5 is 0.4. What should you fix first?Related
Answer: Retrieval: the right source is often not even retrieved
Without the right source, the answer cannot be grounded.
From Evaluating LLM apps
A test for a rare condition is 99% sensitive. Why can most positive results still be false?Related
Answer: Because the healthy group is so large that even a small false positive rate gives many false alarms
This is the base rate fallacy: a small rate times a huge group can beat a large rate times a tiny group.
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.
Next steps
- 3 more topics in “Evaluating models” before its exam: Regression metrics: MAE, MSE, RMSE and R², Overfitting, underfitting and regularisation, Cross-validation and tuning hyperparameters.
- Module 6 exam: Evaluating models · 12 questions · 25 min, without help. 6 topics of this module still to finish first.
- Then the next module, k-NN, decision trees and ensembles. 62 topics left in the course before the final exam.
← Previous: Confusion matrix, accuracy, precision, recall and F1