This page shows the chapter notebook with its saved results. Constructed examples do not measure competition gains.
Chapter 47: Medical Imaging Patterns
Try the decision first
How far does image-level cross-validation overstate the score on new patients, and does grouping by patient remove the error?
Write your expectation before opening the worked results. Use the chapter activity to compare supported inputs. To change the calculation itself, run the notebook on GitHub.
Your answers stay on this page until you download them. They are not sent to a server.
Worked notebook and saved results
How far does image-level cross-validation overstate the score on new patients, and does grouping by patient remove the error?
Several images, slides or tiles usually share one patient. The chapter's rule is to keep each patient in one validation fold; the size of the error it prevents depends on how many images each patient contributes, which this demonstration varies.
Constructed data with patient-level labels; the sizes of these effects are properties of this generator, not a competition result.
The experiment
Constructed cohorts of 150 patients with a patient-level label (half positive). Each image has 12 features: the patient's own anatomy (shared by all of their images and larger than the within-patient noise), a weak disease signal on three features, and image noise. An extremely randomized trees classifier is scored by out-of-fold AUC pooled over five folds, split two ways: ordinary shuffled folds that treat each image alone, and GroupKFold by patient. Both are compared with the same model's AUC on 600 fresh patients, averaged over 8 cohorts. The control is the number of images per patient.
Calculation code
import numpy as np
from sklearn.ensemble import ExtraTreesClassifier
from sklearn.metrics import roc_auc_score
from sklearn.model_selection import GroupKFold, KFold
from kaggle_companion.activities._common import clean
SEED = 47
DRAWS = 8 # independent cohorts; every estimate is a mean over draws
PATIENTS = 150 # development patients; 600 further patients form the fresh test cohort
FRESH = 600
DIM = 12 # image features
def generate(n_patients, images_each, rng):
"""Patient-level label. Each image = the patient's own anatomy (shared by all their images) + a weak disease signal + image noise."""
label = (rng.random(n_patients) < 0.5).astype(int)
anatomy = 1.5 * rng.normal(size=(n_patients, DIM))
patient = np.repeat(np.arange(n_patients), images_each)
y = label[patient]
X = anatomy[patient] + 0.8 * rng.normal(size=(len(patient), DIM))
X[:, :3] += 0.5 * (2 * y[:, None] - 1)
return X, y, patient
def model(seed=0):
return ExtraTreesClassifier(n_estimators=40, max_features=0.5, random_state=seed, n_jobs=1)
def pooled_auc(X, y, splits):
"""Out-of-fold probabilities pooled over all folds, then one AUC."""
oof = np.zeros(len(y))
for fit, hold in splits:
oof[hold] = model().fit(X[fit], y[fit]).predict_proba(X[hold])[:, 1]
return roc_auc_score(y, oof)
def run(images_per_patient):
rng = np.random.default_rng(SEED)
X_new, y_new, _ = generate(FRESH, images_per_patient, rng) # fresh patients: the truth the CV should predict
rows = {k: [] for k in ("kfold", "grouped", "fresh", "overlap_kfold", "overlap_grouped")}
for draw in range(DRAWS):
X, y, patient = generate(PATIENTS, images_per_patient, rng)
kfold = list(KFold(5, shuffle=True, random_state=draw).split(X)) # each image on its own
grouped = list(GroupKFold(5).split(X, y, patient)) # whole patients together
rows["kfold"].append(pooled_auc(X, y, kfold))
rows["grouped"].append(pooled_auc(X, y, grouped))
rows["fresh"].append(roc_auc_score(y_new, model().fit(X, y).predict_proba(X_new)[:, 1]))
# The chapter's check: do validation patients also appear in training? (share of validation images)
rows["overlap_kfold"].append(np.mean([np.isin(patient[b], patient[a]).mean() for a, b in kfold]))
rows["overlap_grouped"].append(np.mean([np.isin(patient[b], patient[a]).mean() for a, b in grouped]))
mean = {k: float(np.mean(v)) for k, v in rows.items()}
return clean({
"images_per_patient": images_per_patient, **mean,
"kfold_error": mean["kfold"] - mean["fresh"], "grouped_error": mean["grouped"] - mean["fresh"],
"per_draw": {k: rows[k] for k in ("kfold", "grouped", "fresh")},
"patients": PATIENTS, "images": PATIENTS * images_per_patient, "fresh_patients": FRESH, "draws": DRAWS,
})
Measure it across the control
The control is images per patient. Each value below runs the whole experiment from the generator up.
Calculation code
import pandas as pd
from kaggle_companion.activities.ch47 import explain
VALUES = [1, 2, 4, 8]
results = {value: run(value) for value in VALUES}
table = pd.DataFrame({str(v): explain(results[v], v)['metrics'] for v in VALUES})
print(table.to_string())1 2 4 8 Image-level 5-fold AUC 0.700 0.791 0.874 0.924 Grouped AUC 0.701 0.683 0.674 0.667 AUC on fresh patients 0.716 0.689 0.707 0.706 Image-level error -0.016 +0.101 +0.167 +0.218 Grouped error -0.015 -0.006 -0.033 -0.039 Patients shared across folds (image-level) 0.0% 81.4% 98.8% 100.0%
Look at it
The figure shows the default setting, images per patient = 4.
Calculation code
import matplotlib.pyplot as plt
from kaggle_companion.activities.ch47 import draw, NCOLS, HEIGHT
DEFAULT = 4
fig, axes = plt.subplots(1, NCOLS, figsize=(6.6 if NCOLS == 1 else 10.4, HEIGHT), layout='constrained')
draw(axes, results[DEFAULT], DEFAULT)
plt.show()What the result says
With 4 images per patient the same model scores AUC 0.707 on fresh patients. Image-level folds report 0.874: 0.874 - 0.707 = 0.167 (their error). Grouped folds report 0.674, which is -0.033 from the fresh score. 98.8% of image-level validation images belong to a patient that is also in training, against 0.0% when grouped. The image-level number measures how well the model recognises patients it has already seen.
- Image-level: 0.874 - 0.707 = +0.167 (estimate minus fresh patients).
- Grouped by patient: 0.674 - 0.707 = -0.033.
- Image-level minus grouped: 0.874 - 0.674 = +0.200.
- Patient overlap between training and validation: 98.8% (image-level), 0.0% (grouped).
Apply this to your competition
- Build the fold column from patient, study or slide identifiers, never from image rows, and keep it fixed for every model.
- Assert that no patient identifier appears in both a training fold and its validation fold.
- Report images per patient next to the score; the more repeats, the larger an image-level error can be.
- Check provenance for hidden links such as duplicate scans, shared slides or external data from the same patients.
Book location: Chapter 47, Keep all images from each patient in one validation fold.
Apply a lesson from this chapter
Select a lesson whose conditions match your project. State how you would test it and what would make you reject it.
Measure resolution and ensemble returns on medical images
Conditions
- small medical features suggest expensive higher-resolution or multi-view inference
Action
- Proposed conditional application: Check whether resolution beyond radius 270 and multi-view/multi-network ensembles improve enough to justify cost.
Check
- Proposed check: Sweep resolution and separately ensemble size on patient holdouts; plot metric versus training/inference cost.
Limits
- 270 is a historical setup result, not universal sufficient resolution; subtle pathology may require higher detail.
Compare breast-to-patient aggregation before final ensembling
Conditions
- breast-level mammography probabilities require a patient-level score
- one patient outcome is predicted from multiple breast-level scores
Action
- Proposed conditional application: Compare mean and maximum breast probabilities when computing patient-level scores within the same ensemble.
- Proposed adaptation of source observation: Compare mean and maximum aggregation on patient-level predictions.
Check
- Proposed check: Compare mean and maximum breast-to-patient aggregation with a fixed ensemble and patient-grouped validation, including unilateral and bilateral cases.
- Proposed verification: Use identical breast predictions and patient labels for the paired AUC comparison.
Limits
- Public AUC comparison may reflect leaderboard tuning; the maximum rule may overreact to a noisy breast score.
- This is a source-reported comparison; the aggregation rule should match the target outcome and is not a universal medical rule.
Keep a simplified detector pipeline as a cost benchmark
Conditions
- a large medical detection ensemble has substantial setup cost
Action
- Proposed conditional application: Compare the full ensemble with the supplied one-classifier plus five-relation-network variant.
Check
- Proposed check: Reproduce small and full pipelines on the same validation, then compare detection quality, model loading, latency and memory.
Limits
- Smaller model count suggests a cost experiment but no measured cost saving is provided; setup still includes several detectors.
Limit degrees of freedom in leaderboard experiments
Conditions
- competition feedback is noisy and repeated submissions are limited
Action
- Proposed adaptation of source observation: Evaluate seed pairs and use coarse hyperparameter changes; proposed adaptation also maintains independent validation.
Check
- Proposed verification: Estimate seed variance and track the number of feedback-driven decisions.
Limits
- Public-only selection can still overfit; coarse search does not guarantee reliability.
Aggregate detected lesions while accounting for missed lesions
Conditions
- case-level cancer prediction depends on multiple detected nodules
Action
- Proposed conditional application: Extract features from detector proposals and combine lesion probabilities with a learned dummy-nodule probability for missed disease.
Check
- Proposed check: Ablate dummy term on patient-held-out log loss/calibration, stratified by detection misses.
Limits
- Noisy-or dependence assumptions and missed-lesion interpretation need validation; full training reported 8 GPUs over days.
- Competition cancer prediction does not establish clinical utility.
Combine paired anatomical predictions in a second stage
Conditions
- two eyes belong to the same case and are available together at inference
Action
- Proposed conditional application: Fit a second-stage Random Forest using predictions from both eyes before mapping to integer labels.
Check
- Proposed check: Train the RF on out-of-fold paired-eye predictions, group folds by patient, and test one-eye missingness and ordinal-label mapping.
Limits
- Both eyes must be available together; patient overlap and in-sample base predictions would bias stacking evaluation.
Budget the diagnostic model before label-cleaning retraining
Conditions
- an out-of-fold noise audit requires its own model training
Action
- Proposed adaptation of source observation: Include the diagnostic folds and prediction pass in the compute budget before committing to a label-cleaning pipeline.
Check
- Proposed verification: Measure one complete fold and estimate total audit plus retraining wall time.
Limits
- These timings are author estimates on a stated setup and do not transfer directly to other hardware.
Audit image-hash duplicate groups before assigning folds
Conditions
- histology slides may include visually duplicated images
Action
- Proposed adaptation of source observation: Inspect image-hash groups before constructing fixed folds and keep confirmed duplicates together.
Check
- Proposed verification: Verify group disjointness across folds and inspect threshold-boundary pairs manually.
Limits
- The README does not establish that its grouping is actually enforced by its split script; grouping enforcement is a proposed check.
Keep all images from each patient in one validation fold
Conditions
- Microscopy tiles share patient origin.
- multiple medical images belong to one patient
Action
- Assign all slides and tiles from a patient to one validation fold.
- Proposed adaptation of source observation: Keep all images of each patient in one validation fold.
Check
- Audit patient disjointness, slide ancestry and held-out segmentation quality.
- Proposed verification: Assert that patient IDs never overlap between training and validation.
Limits
- Patient grouping requires accurate provenance and enough independent patients.
- Balanced mask-area sampling is a separate training decision that alters prevalence.
- The source reports the split choice without comparing against an image-level split.
Harmonize external ordinal labels before pseudo-label training
Conditions
- external image datasets use different ordinal grading conventions
Action
- Proposed adaptation of source observation: Keep external label sources distinct; evaluate smoothing labels with stage-one predictions and group-based label harmonization before retraining.
Check
- Proposed verification: Use trusted held-out grades to check calibration and the incremental contribution of each external source.
Limits
- Model-based relabeling can reinforce bias; threshold changes and added data occur together, so no isolated gain is established.
Treat cross-year validation disagreement as unresolved evidence
Conditions
- historical and current image datasets give conflicting validation feedback
Action
- Proposed adaptation of source observation: Proposed: diagnose cross-year distribution and labeling differences before abandoning an independent holdout.
Check
- Proposed verification: Compare year-held-out and within-year splits, documenting leaderboard disagreement.
Limits
- The source actually used public-only validation; this is a proposed safer adaptation, not their validated solution.
Treat auxiliary-task CV gains as provisional
Conditions
- an age or other auxiliary task appears helpful in cross-validation
Action
- Proposed adaptation of source observation: Require an independent target-task check before retaining an auxiliary loss.
Check
- Proposed verification: Compare matched target-task models and test whether auxiliary labels induce shortcut learning.
Limits
- Overfitting is the author’s hypothesis; the excerpt supplies no controlled diagnosis.
Keep a credible local small-data baseline despite weak public score
Conditions
- public evaluation is noisy for a small MRI dataset
Action
- Proposed conditional application: Retain a simple Gaussian-process classifier supported by leave-one-out validation rather than discarding it solely for weak public score.
Check
- Proposed check: Audit subject independence and preprocessing within LOOCV, compare simple baselines, and quantify uncertainty before reacting to public scores.
Limits
- LOOCV score and kernel are absent; a later private success is not proof the local protocol was unbiased.
Preserve a raw-image branch when cropping mammograms
Conditions
- large medical images include substantial non-breast background
Action
- Proposed adaptation of source observation: Retain raw conversions and a separately indexed cropped-resized branch for controlled preprocessing comparison.
Check
- Proposed verification: Inspect border lesions and verify identical image IDs and intensity handling across branches.
Limits
- Cropping quality and a raw-versus-cropped ablation are not reported.
Normalize retinal scale and lighting
Conditions
- retinal photographs vary in scale and lighting
Action
- Proposed conditional application: Scale retinal photographs to a common radius and subtract local average color before fitting the image model.
Check
- Proposed check: Ablate scale and color correction on patient-held-out grading metrics; inspect lesion visibility and acquisition subgroups.
Limits
- Normalization can erase subtle lesions; no clinical benefit or isolated numerical gain established.
Aggregate informative slide tiles with attention
Conditions
- slide labels supervise a selected subset of histology tiles
Action
- Proposed conditional application: Select sixteen darkest tiles and train slide-level attention pooling instead of average pooling.
Check
- Proposed check: Compare average and attention pooling on identical patient-grouped folds and tile sets; measure tile selection sensitivity and inference cost.
Limits
- More tiles and stain normalization failed in this source; the reported comparison is author evidence on small-data folds.
Assess fold dispersion when selecting small-data medical models
Conditions
- a small public leaderboard cannot distinguish tiny gains
Action
- Proposed conditional application: Use patient-grouped stratified folds and track both mean score and fold deviation; compare self-supervised pretraining by stability.
Check
- Proposed check: Repeat pretraining comparisons on fixed patient-grouped folds and seeds; report mean, dispersion and uncertainty rather than only the best fold.
Limits
- Fold deviation from five folds is imprecise and does not guarantee unseen-patient stability; pretraining adds cost.