Validating a model before it touches patients
A model that looks excellent on last year's data can still fail on tomorrow's patients, which is why clinical AI is tested going forward in time before it is trusted.
- 9 min read
- 3 reading levels
- Published
Read these first
On this page 6
One lesson, three depths. Pick the one that fits you today — you can switch any time.
Beginner — No maths. Plain English.
Prospective validation means testing a model on patients it has never seen before, going forward in time.
Think about a new medicine. Before it reaches a pharmacy shelf, it goes through trials on real patients, watched carefully, over real time. Nobody trusts it based only on old hospital records of people who already got better or worse.
A healthcare AI model deserves the same caution. A model that looks great on last year's data has only proven it can describe the past. It has not yet proven it can handle tomorrow.
Why it exists
It is tempting to believe a model is ready once it scores well on a held-out test set. That test set, though, usually comes from the same time period and the same hospital. It often shares the same broad conditions as the training data.
Real deployment is different in a way that matters. The model now has to handle patients, equipment, and practices it has never seen. All of it arrives in an order it cannot control. A hospital might switch lab vendors. A new clinical guideline might change how a disease gets diagnosed. None of that shows up in a random split of old data — it only shows up going forward.
How it works
Retrospective validation (the common shortcut):
All historical data -> shuffle randomly -> split into train / test
|
v
looks impressive, tests nothing
about the future
Prospective validation (the real test):
Train on the past -> deploy quietly, in "shadow mode" -> compare its
predictions
to what
actually
happens,
going forwardShadow mode means the model runs alongside real clinical care. It makes predictions nobody acts on yet, purely to test it against reality before anyone trusts it.
Where you have already seen it
- An airport security scanner gets tested for months, watched by a human backup, before it works alone.
- A self-driving car feature runs in "shadow" for enormous distances first. It quietly compares its decisions to the human driver's, before it is trusted to steer.
An honest warning
A strong retrospective result is not evidence a model is ready for patients. It shows the model learned something from history. That is necessary — and nowhere near sufficient. Real deployment needs prospective testing, and ongoing monitoring after launch. Anything used in an actual clinical decision also needs regulatory review, and sign-off from clinicians who understand it. No lesson on this site should be mistaken for something ready to guide real patient care. Neither should any toy model built while learning from it.
Remember this
- A model that performs well on old, shuffled data has not yet proven it works going forward.
- Shadow mode lets a model be watched against reality before it makes a real decision.
- Deploying a clinical model is a regulated, clinician-supervised process — not a step a trained model skips into on its own.
What to learn next
- Duplicate rows across your splits — a related reason retrospective numbers can mislead.
- Using the future to predict the past — the general version of the trap this lesson's code example demonstrates.
- When medical AI has caused harm — real, documented cases where this step was skipped or got it wrong.
Developer — Code and libraries.
Setup
pip install scikit-learn pandas numpyMinimal runnable code
import numpy as np
import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_auc_score
rng = np.random.default_rng(0)
n = 1800
# 18 months of admissions. In month 14, the hospital switched lab vendors --
# a routine change nobody flagged as an "AI risk". The new vendor's assay
# responds to the same biology in the opposite direction.
month = np.repeat(np.arange(1, 19), n // 18)
lab_value = rng.normal(10, 2, n)
shifted = month >= 14
risk = np.where(shifted, -0.30 * (lab_value - 10), 0.55 * (lab_value - 10))
prob = 1 / (1 + np.exp(-risk))
outcome = rng.binomial(1, prob)
df = pd.DataFrame({"month": month, "lab_value": lab_value, "outcome": outcome})
# Retrospective validation: shuffle everything, split randomly. The model
# sees examples from both the old and new vendor during training.
shuffled = df.sample(frac=1, random_state=0)
cut = int(len(shuffled) * 0.7)
train, test = shuffled.iloc[:cut], shuffled.iloc[cut:]
model = LogisticRegression().fit(train[["lab_value"]], train["outcome"])
random_split_auc = roc_auc_score(test["outcome"], model.predict_proba(test[["lab_value"]])[:, 1])
# Prospective-style validation: train only on the past, test only on the future.
train_t = df[df["month"] < 14]
test_t = df[df["month"] >= 14]
model_t = LogisticRegression().fit(train_t[["lab_value"]], train_t["outcome"])
temporal_auc = roc_auc_score(test_t["outcome"], model_t.predict_proba(test_t[["lab_value"]])[:, 1])
print(f"random split AUC (mixes both lab vendors into training): {random_split_auc:.3f}")
print(f"forward-in-time split AUC (train months 1-13, test months 14-18): {temporal_auc:.3f}")random split AUC (mixes both lab vendors into training): 0.638 forward-in-time split AUC (train months 1-13, test months 14-18): 0.344
What actually happened
The random split scores 0.638 — mediocre, but plausible-looking. The forward-in-time split scores 0.344, worse than random guessing at 0.5. Same model, same underlying data, same code — the only thing that changed is which rows were allowed to see which.
Here is why: the random split lets training data from after the lab vendor switch leak into the training set, so the model gets a preview of the new relationship it is being tested on. The forward-in-time split trains only on months 1 through 13 — before the switch — and is honestly tested on a world where the relationship between the lab value and the outcome has reversed. It fails, because in the real, deployed sense, it would have failed too.
Line by line, the parts that are not obvious:
df.sample(frac=1, random_state=0)shuffles every row, destroying the time ordering — this single line is the entire difference between the two validation styles.- The AUC below 0.5 in the temporal split is not a bug. A relationship that reverses direction can produce exactly this: a model confidently predicting the opposite of what now happens.
month >= 14is used consistently to define both the shift point and the temporal test cutoff — a real deployment would not know the shift point in advance, which is precisely why ongoing monitoring after deployment matters, not only a single one-time forward split.
Common mistakes
Treating a single forward split as sufficient proof. Real prospective validation continues after deployment, not only once before it — see monitoring and model drift.
Choosing the temporal cutoff based on where performance looks best. That defeats the purpose — the cutoff should reflect a real deployment date, decided in advance, not searched for after the fact.
Assuming a single hospital's temporal validation transfers to a different hospital. It does not, by default — see why your model fails at the next hospital for the imaging version of this exact problem.
Try it yourself
Change the cutoff month >= 14 to month >= 10, giving the temporal test set more of the post-shift data and less pre-shift training data. Watch how much earlier detection of the shift would have changed the outcome — and consider how a real hospital would only learn about this shift by watching for it.
What to learn next
- Using the future to predict the past — the general form of the bug this example exposes.
- Monitoring and model drift — what happens after the model is deployed and watched, not tested only once.
- When medical AI has caused harm — what goes wrong when this step is skipped entirely.
Researcher — Mathematics and papers.
The validation hierarchy
Clinical AI validation is generally described in three increasingly strict stages:
1. Retrospective internal validation - held-out split of historical data, same institution
2. Retrospective external validation - held-out data from a DIFFERENT institution
3. Prospective validation - new data collected AFTER the model was frozen,
ideally in silent/shadow mode before any
clinical action is taken on its outputEach stage answers a narrower, more demanding question than the last. Passing stage 1 says almost nothing about stage 3 — this is the core finding formalised by the temporal-shift demonstration in the developer block above, and documented repeatedly in the clinical AI literature.
Regulatory framing
In the United States, an AI system intended to inform a clinical decision is regulated by the FDA as Software as a Medical Device (SaMD). The first FDA-authorised fully autonomous AI diagnostic system was IDx-DR (2018), for detecting diabetic retinopathy from retinal images without requiring a specialist to interpret the image. Its pivotal trial (Abramoff et al., 2018, npj Digital Medicine) was a prospective study conducted across primary care sites, explicitly structured to test the system going forward on patients it had not influenced — the pattern this lesson describes, applied at regulatory scale. The European equivalent regulatory pathway is CE marking under the Medical Device Regulation (MDR), with its own, differently structured evidence requirements. Neither pathway is optional for a system intended to inform real patient care, and neither is something a model earns by scoring well on a public benchmark dataset.
Distribution shift, formally
Let P_train(x, y) be the joint distribution the model was trained on, and P_deploy(x, y) the joint distribution it will actually see. Retrospective random-split validation estimates performance under P_train. Real deployment performance depends on P_deploy. The two coincide only under the assumption that nothing about the data-generating process changes between training and deployment — an assumption the developer block's lab-vendor example violates by construction, and one that real hospitals violate routinely, through equipment changes, staffing changes, and shifting patient populations.
Key references
- Abramoff, M. et al. (2018). Pivotal trial of an autonomous AI-based diagnostic system for detection of diabetic retinopathy in primary care offices. npj Digital Medicine 1.
- Topol, E. (2019). High-performance medicine: the convergence of human and artificial intelligence. Nature Medicine 25.
- Park, S. & Han, K. (2018). Methodologic Guide for Evaluating Clinical Performance and Effect of Artificial Intelligence Technology for Medical Diagnosis and Prediction. Radiology 286(3). A widely cited methodological checklist for exactly this validation hierarchy.
- Wong, A. et al. (2021). External Validation of a Widely Implemented Proprietary Sepsis Prediction Model. JAMA Internal Medicine. A case where the gap between retrospective and real-world performance was large.
Current state
Regulatory frameworks worldwide are actively evolving to handle models that continue learning after deployment ("continuously learning" or "adaptive" SaMD), which existing static-validation frameworks were not designed for. This remains an open regulatory question, not a solved one, as of this writing.
What to learn next
- Using the future to predict the past — the general statistical mechanism behind the demonstration above.
- Monitoring and model drift — the ongoing half of prospective validation, after initial deployment.
- When medical AI has caused harm — documented consequences when this discipline was insufficient.