THE MODEL AND THE RADIOLOGIST CANNOT BE TOLD APART, AND THE CONTEST WAS NEVER FAIR. On 223 biopsied lesions of which 87 were malignant, a logistic regression on the radiologist's recorded descriptors scores AUC 0.837 against 0.851 for that radiologist's own BI-RADS assessment — a difference of -0.0136 with a 95% interval of [-0.070, +0.044]. The interval spans zero, so no difference is established. It could not have been: the model's inputs are the radiologist's judgement written down, recorded in the same reading that produced the assessment. A tie shows the descriptors carry the assessment, and nothing more.
An accuracy figure is a statement about a cohort, not about a model
On 223 biopsied breast lesions, does a model built from a radiologist's own recorded descriptors beat that radiologist's own assessment — and what is the accuracy figure silently conditional on?
What the analysis found, including the results that went against us
Each of these came out of the run. None has been softened.
Where the bootstrap difference lands
Distribution of the difference in AUC between the model and the radiologist's own assessment across 2,000 bootstrap resamples of lesions. It straddles zero.
run.py section 2: paired bootstrap over lesions.
THE COHORT DECIDES THE NUMBER BEFORE THE MODEL DOES. Every lesion here was biopsied — that is how a pathology label exists — so 39.0% of them are malignant. Hold this classifier's sensitivity (0.80) and specificity (0.69) fixed and move only the population: positive predictive value falls from 62.5% here to 1.29% at a screening rate of 0.5%, a factor of 48. Nothing about the model changed. A reported PPV without its cohort's prevalence beside it is not interpretable.
Cost by threshold, at two cost ratios
Expected cost per lesion against decision threshold, when a false negative costs the same as a false positive and when it costs twenty times more. Both curves are flat over a wide range, so the optimum is not a single point.
run.py section 4: cost as a step function of the threshold.
THE OPTIMAL THRESHOLD IS NOT A POINT AND OFTEN NOT IDENTIFIED. With 223 lesions the cost function is a step function, so an interval of thresholds achieves the same minimum. At equal costs every cut between 0.550 and 0.640 is indistinguishable — a range 0.090 wide. When a false negative is costed twenty times a false positive the optimum moves to 0.100 to 0.100. Publishing a threshold to three decimal places implies a precision this much data cannot support.
Positive predictive value against prevalence
Positive predictive value of the same fixed classifier as the malignancy rate of the population changes. Sensitivity and specificity are held constant throughout — only the cohort moves.
run.py section 3: PPV recomputed at each prevalence.
THE FIELD'S DEFAULT BENCHMARK IS BEATEN TO WITHIN 6.1 POINTS BY ONE DECISION RULE. On the 569-row Wisconsin diagnostic dataset, logistic regression on all 30 features reaches 95.43% under ten-fold cross-validation. A decision stump — a single threshold on worst radius, the simplest non-trivial classifier that exists — reaches 89.29%. A method reporting 97 or 98 per cent on this data has not demonstrated anything the stump does not, and the benchmark cannot distinguish methods that differ by less than that.
A LESION PHOTOGRAPHED TWICE IS ONE LESION AND TWO ROWS. The training file has 1,318 rows describing 782 lesions in 691 patients, because 536 lesions were imaged from two angles. Reporting at row grain inflates the apparent sample by 68.5%, and every row of a pair carries the same pathology label — so a random split puts the same outcome on both sides. This file ships with an official split whose patient overlap is exactly 0, which is the correct design and is worth noticing, because a split that does not do this is common.
THE PATTERN REPLICATES ON AN INDEPENDENT COHORT. On the UCI Mammographic Mass data — 961 lesions from a different institution and a different decade, 830 of them complete — a model on the recorded descriptors scores AUC 0.872 against 0.825 for the radiologist's BI-RADS, a difference of +0.047. The donors of that dataset flag BI-RADS as non-predictive and exclude it from modelling for exactly this reason. Two cohorts, same result: a model of a radiologist's description performs like the radiologist.
Full results tables
Rows are not lesions and lesions are not patients
| Split | Rows | Lesions | Patients |
|---|---|---|---|
| Training | 1,318 | 782 | 691 |
| Test | 378 | 223 | 201 |
The same classifier, in three populations
| Malignancy rate | Positive predictive value |
|---|---|
| 0.5% | 1.3% |
| 2.0% | 5.0% |
| 39.0% | 62.5% |
The 569-row benchmark
| Method | 10-fold accuracy |
|---|---|
| Logistic regression, all 30 features | 95.43% |
| Decision tree, unrestricted | 91.74% |
| One-split stump on worst radius | 89.29% |
Limitations
Stated by the analysis, not added afterwards. A project without these is not finished.
- NOT A CLINICAL STUDY, AND NOT A DIAGNOSTIC CLAIM. Nothing here was validated for clinical use, no figure below should inform any decision about any patient, and none of this was reviewed by a clinician. It is an audit of what an accuracy figure is conditional on, carried out on public research data, and its subject is measurement practice rather than medicine.
- The imaging is historical. CBIS-DDSM is digitised screen-film mammography from the 1990s, and nothing here supports any statement about screening with modern full-field digital mammography or tomosynthesis. The measurement lessons transfer; the performance figures do not.
- The test cohort is small and every interval here is wide. 223 lesions and 87 cancers give bootstrap AUC intervals roughly a tenth of an AUC wide, which is why the difference is published as an interval and not as a point estimate. A study of this size cannot distinguish two methods that are genuinely close.
- The 2% biopsy threshold referenced here is defined over screening-detected findings, where malignancy is rare. Applying it to a cohort where every lesion was already biopsied is deliberately the wrong population, and that mismatch is the demonstration rather than an oversight — a threshold carried across cohorts without adjusting for prevalence is the error being shown.
- The model's features are not independent measurements of the lesion. Shape, margins, subtlety and density are a radiologist's structured description, recorded in the same reading that produced the assessment, so the comparison in step 2 is circular by construction. That circularity is the finding; it is not a design that should be copied to claim a model matches a clinician.
- 34 lesions carry no recorded margin and 1 no recorded shape. They are encoded as an all-zero block rather than imputed, which makes 'not described' its own category. That is defensible — the absence is a fact about the reading — but it is a choice, and a study that imputed instead would report different figures on the same file.
- BENIGN_WITHOUT_CALLBACK is collapsed into benign. That is the standard reading — the finding was judged not to require a further visit — but it moves the class balance, and a study that treated those lesions differently would report different figures on the same file.
- Only the metadata is used. The 163 GB image collection is not downloaded, because it requires a desktop client that no script can drive, and therefore no reader could reproduce a figure derived from it. Nothing here is a claim about what a model reading pixels could achieve.
Data: CBIS-DDSM curated breast imaging subset (case description metadata), with UCI Mammographic Mass and UCI Breast Cancer Wisconsin (Diagnostic), CBIS-DDSM curated breast imaging subset (case description metadata), with UCI Mammographic Mass and UCI Breast Cancer Wisconsin (Diagnostic), CBIS-DDSM curated breast imaging subset (case description metadata), with UCI Mammographic Mass and UCI Breast Cancer Wisconsin (Diagnostic), CC BY 3.0 (TCIA, DOI 10.7937/K9/TCIA.2016.7O02S9CY) and CC BY 4.0 (UCI). 2,446 rows, DDSM films digitised in the 1990s; Mammographic Mass 2003-2006; Wisconsin 1995.
Libraries and methods this analysis used
Read from this project's own run.py when the page was built — 500 lines of it. Not a list of everything we know; a list of what this analysis imports and calls.
8 names from NumPy appear in this analysis.
- column_stack
- errstate
- histogram
- isfinite
- linspace
- median
- percentile
- random
6 names from pandas appear in this analysis.
- Categorical
- agg
- astype
- dropna
- groupby
- read_csv
5 names from scikit-learn appear in this analysis.
- DecisionTreeClassifier
- LogisticRegression
- cross_val_score
- load_breast_cancer
- roc_auc_score
How every number on this page is checked
A script deletes each result file, re-runs the project and diffs the output. If a headline figure moves, the check fails, and the page does not ship. That is the only reason to believe anything on this page.
Running this method on your own data
The method above transfers; the result will not. Send us a extract and we will tell you what is forecastable in it and what is not, before anyone signs anything.