The idea
Every hard classification decision lands in one cell of the confusion matrix:
| Predicted + | Predicted − | |
|---|---|---|
| Actual + | TP | FN |
| Actual − | FP | TN |
All the named metrics are just ratios over this table, each answering a different question:
- Precision — alert quality: when the model shouts, is it right?
- Recall — coverage: of the real positives, how many did we catch?
- Accuracy — overall correctness, which silently assumes classes are balanced and errors cost the same. With a 97% negative base rate, the all-negative model scores 97% — check the majority baseline before quoting accuracy, ever.
Precision and recall fight through the threshold: flag more (lower threshold) and recall rises while precision drifts down toward the base rate. F1 compresses the pair into one number using the harmonic mean,
which is dominated by the weaker of the two — you cannot F1-launder a degenerate classifier ( gives , not ). generalizes: weights recall more ( for screening), weights precision.
ROC-AUC evaluates the scores rather than one thresholded decision. The ROC curve plots TPR against FPR as the threshold sweeps; the area under it equals the probability that a random positive outranks a random negative. AUC 0.5 = coin-flip ranking, 1.0 = perfect separation. It is threshold-free and invariant to monotone score transforms — which is both its power (fair model comparison) and its blind spot (says nothing about calibration or about performance at your operating point, and can look rosy under heavy imbalance because FPR divides by a huge negative count).
Move one decision threshold. The model scores stay fixed; every metric and cost changes around that choice.
Cost assumes $10 per false alarm and $500 per miss. Lower thresholds catch more positives; prevalence determines how many false alarms surround them.
Worked example
A disease classifier on patients, prevalence 6% (60 positives):
| Predicted + | Predicted − | |
|---|---|---|
| Actual + (60) | TP = 40 | FN = 20 |
| Actual − (940) | FP = 10 | TN = 930 |
The readings that matter:
- Accuracy 0.97 sounds superb — but all-negative scores 0.94. The model's entire contribution lives in that 3-point gap; precision/recall expose it directly.
- Precision 0.80: 1 in 5 alarms is false. Recall 0.667: a third of true cases walk out undetected — likely the number a medical stakeholder cares about most.
- Raising the threshold would trade recall down for precision up; whether that is good depends entirely on the cost of an FN (missed disease) vs an FP (unnecessary follow-up test) — the matrix cannot decide that for you.
Cheat sheet
From the matrix: , , , , .
| You care about | Reach for |
|---|---|
| Cost of false alarms | precision |
| Cost of misses | recall ( if you need one number) |
| Ranking quality, model comparison | ROC-AUC |
| Rare positives, alert budgets | precision-recall curve, PR-AUC |
| Probability quality / calibration | log loss, Brier score, reliability curve |
| Overall correctness, balanced classes | accuracy (vs majority baseline) |
- ROC-AUC for random +/− pair; threshold-free; monotone-invariant; 0.5 = random.
- Threshold up ⇒ recall down, precision (typically) up; threshold down ⇒ recall → 1, precision → prevalence.
- Accuracy floor to beat: for prevalence .
- F1 ignores TN entirely — sensible for needle-in-haystack tasks, misleading when true negatives are what you value.
- Harmonic-mean trap: , ⇒ .
- Report the operating point WITH the metric: "P/R at threshold t," never bare F1 with an unstated default threshold.