Measured, Not Believed ← all audits
Case study · base rates · reproducible

0.978 AUC, 12% precision

Both numbers describe the same model on the same day. Neither is a mistake, and the gap between them is the most expensive thing I know about benchmarks — because almost nobody prices it in.

A benchmark hands a model a balanced problem: roughly as many positives as negatives, curated and labelled. Area under the ROC curve asks a question suited to exactly that world — draw one of each; how often do you rank them correctly? Nearly always, it turns out. It is a genuinely good model.

Then you take it somewhere the interesting class is rare. The model keeps its skill. The world changes underneath it.

Where the collapse comes from

Precision — the share of your alarms that are real — is not a property of the model alone. It is a property of the model and how often the thing occurs. Bayes' rule, in the only form that matters here:

precision = TPR·π ⁄ (TPR·π + FPR·(1−π))

where π is prevalence. The term that kills you is FPR·(1−π). When positives are rare, 1−π is nearly everyone, so even a small false-positive rate is applied to a very large population — and that flood of false alarms can easily exceed the entire population of true ones.

A real predictor, reprojected

Taking the leading model on a public clinical variant-effect benchmark at its published operating characteristics, and holding the model completely fixed:

SettingPrevalencePrecision of a positive callWhat that means
Benchmark ~50% (balanced) high — AUC 0.978 state of the art, honestly
Clinic 1% ≈ 12% ~7 of every 8 alarms are false
Screening programme 0.1% ≈ 1% ~99 of every 100 alarms are false

Nothing in the leaderboard warns you. The ranking does not change. The model does not degrade. What changes is the base rate — and the base rate never appears in the metric that gets published, quoted and funded.

This is not a genomics problem

It is the shape of every screening claim in machine learning. Fraud detection. Security triage. Content moderation. Insider-threat scoring. Defect finding. Anywhere the interesting class is rare, a benchmark score describes a world with a suspiciously convenient class balance, and deployment does not live there.

I have been on the wrong end of it with my own work: a bug-finding pipeline that looked excellent on a held-out set and was close to useless against a real codebase — because real codebases are mostly not vulnerable, and the pipeline's small false-positive rate met a very large number of clean files.

The fix costs one line

Before you quote the score, state the prevalence you expect in the field and recompute what fraction of your alarms will be real at that prevalence. It belongs in the abstract, beside the headline number — not in a supplementary table where nobody meets it.

And if the answer is uncomfortable, that is the finding. A detector that fires mostly on innocents is not a bad model; it is a good model deployed at a base rate its threshold was never chosen for. That is fixable — by moving the threshold, by triaging in stages, by narrowing who gets screened — but only once someone computes the number.

Reproduce
Take any published detector's TPR and FPR at its stated operating point.
Apply Bayes: precision = TPR·π / (TPR·π + FPR·(1−π)) for the prevalence you actually face.
Clinical variant-effect benchmark, leading predictor: AUC 0.978 → ≈12% precision at π=0.01, ≈1% at π=0.001.
Deterministic — no sampling, no fitting, no room for interpretation.
Run it yourself: the in-browser calculator (check 5) or
evalgate baserate --tpr 0.95 --fpr 0.05 --prevalence 0.01 · github.com/ipezygj/evalgate
Before you publish a screening claim

Tell me the prevalence you'll actually face.

I'll tell you what your headline number becomes there — clinical, security, fraud or moderation. Independent, reproducible, plain-English.