Machine Learning · Insper

ROC and PR

Fundamental approach

Scoring a model at every threshold, then picking one

A scoring model is a family of classifiers

Pick a threshold \(t\), flag everyone with score \(\geq t\), and you get one confusion matrix. Two rates summarize it:

\[ \text{TPR} = \text{recall} = \frac{TP}{TP + FN} \qquad \text{FPR} = \frac{FP}{FP + TN} \]
  • TPR (true positive rate) is the share of the sick that we catch;
  • FPR (false positive rate) is the share of the healthy that we alarm.

TP, FN, FP and TN: true positives, false negatives, false positives and true negatives.

On the 20 patients at \(t = 0.5\): TPR = 7/10, FPR = 2/10, one point \((0.2,\ 0.7)\). Change the threshold and the point moves — that path is the ROC (receiver operating characteristic) curve.

The path of this part

  1. ROC curveeach threshold is a point: sick caught against healthy alarmed
  2. One number: AUCAUC (area under the curve) = the share of (sick, healthy) pairs in the right order
  3. Precision–recall curveaverage precision; why it shows a rare class that ROC hides
  4. Choose the thresholdfour criteria, decided on validation; a formula when scores are calibrated
Each stage answers one question: how does the model do at every threshold? → how good is the ranking as a whole? → what changes when the positive class is rare? → which threshold goes into production?
Stage 1 · How does the model do at every threshold?

Each row of the table is a threshold

patientscoresickTPFPTPRFPR
P010.951100.10.0
P040.801400.40.0
P050.750410.40.1
P090.551720.70.2
…………………
P200.02010101.01.0
The rule is mechanical: passing a sick patient moves up by 1/10; passing a healthy one moves right by 1/10.

The ROC staircase

ROC staircase of the 20 patients, with the 0.5 threshold point and the shaded area 0.86
  • (0, 0): nobody flagged;
  • (1, 1): everybody flagged;
  • the diagonal: random scores — flags sick and healthy at the same rate.
A good model rises early: it finds the sick first. A perfect one goes straight up to (0, 1) and only then to the right.

Simulator: slide the threshold

Predict. Same idea on 600 simulated scores (500 negatives, 100 positives). Lower the threshold from 0.5: which way does the ROC point move, and what happens to precision?

Stage 2 · How good is the ranking as a whole?

AUC, two ways

As an area

The AUC (area under the curve) is the area under the staircase. Each healthy patient adds a rectangle of width 1/10 and height equal to the current TPR:

\[ \begin{aligned} \tfrac{1}{10}\,(&0.4 + 0.6 + 0.8 + 0.9 + 0.9 \\ &+ 5 \times 1.0) = 0.86 \end{aligned} \]

As pairs

Of the 10 × 10 = 100 (sick, healthy) pairs, in how many does the sick one score higher?

\[ \begin{aligned} \tfrac{1}{100}\,(&4 + 6 + 8 + 9 + 9 \\ &+ 5 \times 10) = \tfrac{86}{100} = 0.86 \end{aligned} \]
No coincidence: \(\text{AUC} = P(\text{score of a sick} > \text{score of a healthy})\), ties counting half. It is the most useful way to read an AUC.

AUC measures how far apart the classes are

Histograms of healthy N(0, 1) and sick N(d, 1) scores for d = 0.5, 1.5 and 3, and the ROC curve of each case, with AUC 0.641, 0.850 and 0.984
The less the distributions overlap, the larger the AUC: here, \(\text{AUC} = \Phi(d/\sqrt{2})\). No threshold separates overlapping classes; moving the threshold only picks a point on the same curve.

Only the order matters

transformation of the scoresAUC
score0.86
score ** 20.86
log(score)0.86
100 * score - 70.86
1 - score (reverses the order)0.14
AUC says nothing about calibration: scores all between 0.40 and 0.41 can still give AUC 0.99.
AUC says nothing about one threshold: it averages over all of them, including ones you would never use.

AUC 0.14 is not a bad model: it is a good model with the labels flipped.

Scores, not labels


# wrong: predicted labels (output of predict)
labels = (score >= 0.5).astype(int)
roc_auc_score(sick, labels)             # 0.75  ← NOT the model's AUC
balanced_accuracy_score(sick, labels)   # 0.75  ← this is what you computed

# right: scores (predict_proba(X)[:, 1])
roc_auc_score(sick, score)              # 0.86  ← the model's AUC
  
  • With only two distinct values, the "curve" has one point, joined to the corners by straight lines.
  • Its area becomes \((\text{TPR} + \text{TNR})/2\), with TNR = true negative rate (specificity), which is balanced accuracy at 0.5.
Always pass predict_proba(X)[:, 1] or decision_function(X). The mistake raises no exception at all.
Stage 3 · What changes when the positive class is rare?

The precision–recall (PR) curve

The PR curve of the 20 patients, a sawtooth, with the baseline at prevalence 0.5

ROC looks at the two classes separately. The doctor asks something else: of the patients I flag, how many are really sick?

  • each sick patient: recall rises and precision rises a little;
  • each healthy one: recall stays and precision falls.
The "no skill" line is a horizontal at the prevalence (0.5 here), not the diagonal.

Average precision (AP)

\[ \text{AP} = \sum_k (R_k - R_{k-1})\,P_k = \text{the mean precision at each sick patient} \]
computationvalue
AP by hand (mean of 1, 1, 1, 1, 0.833, 0.857, 0.778, 0.8, 0.75, 0.667)0.8685
average_precision_score0.8685
auc(recall, precision) — trapezoidal area0.8608
Between two PR points precision does not vary linearly with recall: the straight line describes classifiers that do not exist and the trapezoid can be optimistic (Davis & Goadrich, 2006). Report the AP.

When the positive class is rare

The same scorer, changing only how many sick patients exist:

prevalenceAUCAPTPRFPRprecision
50%0.9210.9220.800.120.87
10%0.9220.6660.800.120.42
1%0.9140.2520.790.120.06
The three ROC curves coincide while the PR curves collapse as prevalence falls

Precision in terms of prevalence

Precision: of the flagged patients, the fraction that is really sick, \(TP/(TP + FP)\). Prevalence \(\pi\): the fraction of sick people in the population. Among \(N\) people:

how manyhow many the model flags
sick\(\pi N\)\(TP = \text{TPR} \cdot \pi N\)
healthy\((1-\pi) N\)\(FP = \text{FPR} \cdot (1-\pi) N\)
\[ \text{precision} = \frac{TP}{TP + FP} = \frac{\pi \cdot \text{TPR}}{\pi \cdot \text{TPR} + (1-\pi)\cdot \text{FPR}} \qquad (N \text{ cancels}) \]
Same scorer, TPR 0.80 and FPR 0.12:
\(\pi = 0.5 \;\Rightarrow\; 0.40/(0.40 + 0.06) = \mathbf{0.87}\)
\(\pi = 0.01 \;\Rightarrow\; 0.008/(0.008 + 0.119) = \mathbf{0.06}\)

Why: look at the denominators

  • FPR divides by the number of healthy: a property of the model within one class, blind to how many sick exist;
  • precision divides by the flagged, which mixes the two classes in proportion to their sizes.
A 12% false alarm rate sounds small, but 12% of 100,000 healthy people is 12,000 false alarms against about 800 true ones.
ROC / AUC: both classes matter, or prevalence will change. Prevalence-free by construction.
PR / AP: the positive class is rare and you pay for the flagged cases. Read AP against the prevalence.
Stage 4 · Which threshold goes into production?

Choosing the threshold: four criteria

criterion\(t\)
max F10.35
Youden's J = TPR − FPR0.45 or 0.35
recall ≥ 0.9, best precision0.35
min cost, FN = 10 FP0.20

F1: harmonic mean of precision and recall. The default 0.5 costs 32; the minimum costs 5.

Recall, precision, F1 and Youden's J against the threshold, and the cost curve
The criteria disagree because they declare different costs. The choice belongs to the application and is made on validation.

When scores are calibrated, there is a formula

\[ p > t^* = \frac{c_{FP}}{c_{FP} + c_{FN}} = \frac{1}{1 + 10} \approx 0.09 \]
  • flagging a patient with probability \(p\) costs \((1-p)\,c_{FP}\) on average; not flagging costs \(p\,c_{FN}\);
  • flag when the second is larger (Elkan, 2001).
On the 20 patients, \(t = 0.10\) costs 7, close to the empirical minimum of 5 but not equal: the scores are not perfectly calibrated. The formula says where to look; validation says where to stop.

0.5 is the right threshold only when both mistakes cost the same and the scores are calibrated.

Summary

ROCprecision–recall
axesFPR × TPRrecall × precision
denominatorseach class on its ownthe flagged column
"no skill" linethe diagonalhorizontal at the prevalence
summaryAUC = P(sick above healthy)AP = mean precision at positives
changes with prevalence?noyes
The curve is the model; the point on it is your decision, and it can change later without retraining anything.
Fundamental lab · about 35 min, in pairs

Mammography: the curves, steps 1 to 5

  • 11,183 regions, 2.3% malignant; the task is to flag them for a radiologist.
  • Notebook on Colab (in Portuguese): nothing to download. Save a copy to your Drive.
  • In each step, answer the Predict before running.
  • Simulations: AUC only sees the order (step 4) and the price of each point of recall (step 5).

Pace: steps 1 to 3 in 10 min; step 4 and its simulation in 12 min; step 5 and its simulation in 13 min.