Skip to content

Medical AI · Evaluation, safety & deployment · Lesson 5 of 5

Monitoring and MLOps

Reviewed by Dr. Ram Kumar G, MBBS, MD (Internal Medicine), MPH (USA), on · Last updated

  • Intermediate
  • Technical focus
  • About 30 minutes
  • Includes exercise

Before this lesson: External validation and dataset shift

In short

A clinical model's performance can change after go-live because patients, practice, coding or equipment change. Monitoring tracks the model's inputs (are they drifting?), its outputs, and, once outcomes are known, its calibration and discrimination, with alerts when they move outside agreed limits. MLOps is the engineering discipline that makes this routine: versioned models and data, reproducible pipelines, controlled updates and rollback. Regulators increasingly expect it, for example through change-control plans for AI devices.

You will learn to

  • Explain why model performance drifts after deployment, with clinical examples
  • Monitor input drift with the population stability index and calibration with observed/expected ratios
  • Design alerts and responses for drift, including when outcomes arrive late
  • Describe MLOps practices and regulatory expectations for updating clinical models

Why deployed models drift

Davis and colleagues showed that the calibration of acute kidney injury models drifted over the years after development, for both regression and machine-learning models. A widely used sepsis model's alert volume rose sharply across 24 US hospitals at the start of the COVID-19 pandemic, as patients and practice changed (Wong et al., 2021).

ChangeExampleFirst visible in
MeasurementA new lab assay, scanner or coding systemInput distributions
Case mixA new referral pathway, a pandemicInput and output distributions
PracticeNew treatments or guidelines change outcomesOutcomes and calibration, often months later
Feedback loopsThe model's own alerts change care and therefore outcomesOutcomes; hard to separate from model error
SoftwareUpstream data feeds or EHR updates alter inputsInput distributions, sometimes as sudden jumps

Monitoring inputs and calibration over time

The simulation runs a kidney-risk model for 12 months. In month 7 the laboratory switches to an eGFR assay that reads 15 units higher. Two metrics are tracked each month: the population stability index (PSI) for eGFR, which measures how far its distribution has moved from the development data, and the observed-to-expected (O/E) outcome ratio.

python
import numpy as np
import pandas as pd
from sklearn.linear_model import LogisticRegression

rng = np.random.default_rng(11)
predictors = ["age", "egfr", "albuminuria"]

def month_of_patients(n, assay_bias=0.0):
    d = pd.DataFrame({"age": rng.normal(60, 10, n).round(),
                      "true_egfr": rng.normal(70, 20, n).clip(15, 120),
                      "albuminuria": rng.binomial(1, 0.3, n)})
    logit = -2.0 + 0.02 * (d.age - 60) - 0.04 * (d.true_egfr - 70) + 1.0 * d.albuminuria
    d["outcome"] = rng.binomial(1, 1 / (1 + np.exp(-logit)))
    d["egfr"] = (d.true_egfr + assay_bias).round()
    return d

development = month_of_patients(8000)
model = LogisticRegression(max_iter=1000).fit(development[predictors], development.outcome)

def psi(expected, actual, bins=10):
    """Population stability index: how far a variable's distribution has moved from baseline."""
    edges = np.quantile(expected, np.linspace(0, 1, bins + 1))
    edges[0], edges[-1] = -np.inf, np.inf
    e = np.histogram(expected, edges)[0] / len(expected)
    a = np.histogram(actual, edges)[0] / len(actual)
    e, a = np.clip(e, 1e-6, None), np.clip(a, 1e-6, None)
    return float(np.sum((a - e) * np.log(a / e)))

print("month  eGFR PSI  observed  expected  O/E   alert")
for month in range(1, 13):
    d = month_of_patients(600, assay_bias=15 if month >= 7 else 0)   # new lab assay from month 7
    expected = model.predict_proba(d[predictors])[:, 1].mean()
    observed = d.outcome.mean()
    drift = psi(development.egfr, d.egfr)
    alerts = [a for a, bad in [("input drift", drift > 0.2),
                               ("calibration", not 0.8 <= observed / expected <= 1.25)] if bad]
    print(f"{month:>5}  {drift:8.2f}  {observed:8.1%}  {expected:8.1%}  "
          f"{observed / expected:4.2f}  {', '.join(alerts)}")

# month  eGFR PSI  observed  expected  O/E   alert
#     1      0.01     18.0%     19.8%  0.91
#     2      0.01     22.3%     19.1%  1.17
#     3      0.01     18.8%     19.3%  0.98
#     4      0.02     20.8%     19.3%  1.08
#     5      0.01     20.3%     19.2%  1.06
#     6      0.02     19.7%     17.5%  1.12
#     7      0.54     19.3%     12.3%  1.57  input drift, calibration
#     8      0.50     19.0%     12.7%  1.49  input drift, calibration
#     9      0.57     18.7%     12.4%  1.51  input drift, calibration
#    10      0.55     18.7%     12.1%  1.54  input drift, calibration
#    11      0.64     20.2%     11.7%  1.72  input drift, calibration
#    12      0.61     20.7%     11.8%  1.76  input drift, calibration
Twelve months of synthetic monitoring, with a lab assay change in month 7.
  • Months 1–6 show normal noise: O/E moves between 0.91 and 1.17 without crossing the alert limits.
  • From month 7, eGFR's PSI jumps above 0.5 (above 0.2 is a common rule of thumb for significant shift) and the model underestimates risk by about a third (O/E around 1.5).
  • In real life the outcome here takes years to occur, so the calibration column would not be available in month 7. Input monitoring is the early warning; outcome monitoring confirms later.

Responding to an alert

  • Agree alert limits, owners and response times before go-live, not after the first alert.
  • Monitor subgroups as well as the whole population; drift can affect one group first.
  • Keep a way to switch the model off quickly, and a plan for what clinicians do when it is off.
AlertFirst questionsPossible actions
Input driftDid a lab, device, code set or data feed change?Fix the data mapping; adjust inputs; pause the model if outputs are unreliable
Output shiftAre more or fewer patients flagged, and why?Check case mix and inputs; review alert burden with clinicians
Calibration driftIs the shift uniform, or in particular groups?Recalibrate; review subgroups; consider updating the model
Discrimination dropHas the clinical relationship changed?Re-validate; retrain or retire the model

MLOps: making updates safe

Regulators expect a total-product-lifecycle approach. The FDA, Health Canada and the UK MHRA published ten Good Machine Learning Practice principles in 2021, including monitoring deployed models. The FDA's guidance on predetermined change control plans (PCCPs) lets manufacturers of AI-enabled devices specify in advance which modifications they will make and how they will validate them. Its January 2025 draft guidance on lifecycle management of AI-enabled device software functions was still in draft as of mid-2026; check the current status.

PracticeWhat it gives you
Version control for code, data and modelsKnow exactly which model produced each prediction
Reproducible training pipelinesRebuild or audit any version
Prediction loggingInputs, outputs and model version for every prediction, for monitoring and investigation
Staged releaseShadow mode (run silently alongside practice) before going live; gradual roll-out
RollbackReturn to the previous version if a new one misbehaves
Model documentationIntended use, data, performance, limits and monitoring plan, kept current

Locally deployed models need owners

  • Whether a model is a regulated device or an in-house tool, someone must own its monitoring, respond to alerts and decide when to update or retire it. Feng and colleagues describe this as continual quality improvement for clinical AI.

Exercise

Build a monitoring dashboard for a synthetic deployed model and design the response to drift.

Data: Synthetic monthly data generated in the notebook (no real patient data) (Generated in the notebook)

  1. Reproduce the 12-month monitoring table and plot PSI and O/E over time with the alert limits.
  2. Add PSI for age and albuminuria, and a monthly AUROC once outcomes are available.
  3. Simulate a gradual case-mix change (age rising by one year each month) and see when the alerts fire.
  4. Recalibrate the model on months 7–9 and show monitoring for months 10–12 after the update.
  5. Write a one-page monitoring plan: metrics, limits, owner, response times and how to switch the model off.

The runnable notebook and worked solution will be published soon. You can work through the steps with the code on this page in the meantime.

Key takeaways

  • Deployed models drift as measurement, case mix, practice and software change.
  • Monitor inputs for early warning, and calibration and discrimination once outcomes arrive.
  • Agree alert limits, owners and responses, including switching off, before go-live.
  • Version, log and stage every update; regulators expect lifecycle management.

Terms used: Calibration, Dataset shift, MLOps, Population stability index (PSI)

Related: External validation and dataset shift, Calibration and decision-curve analysis, Regulation, ethics & governance track

FAQ

What is model drift?

A change in a model's performance after deployment, usually because the data it receives or the relationships it learned have changed.

What is the population stability index?

A measure of how much a variable's distribution has shifted from a baseline, calculated over bins. Values above about 0.2 are commonly treated as a significant shift.

How can drift be detected when outcomes take years?

By monitoring inputs and outputs, which are available immediately, and using shorter-term proxy outcomes where valid. Outcome-based calibration checks confirm problems later.

What is MLOps?

Machine learning operations: practices for versioning, deploying, monitoring and updating models reliably, similar to DevOps for software.

What is a predetermined change control plan?

An FDA mechanism that lets manufacturers of AI-enabled devices describe in advance the modifications they plan and how they will validate them, so that those changes can be made within the authorised plan.

Educational content only. This material teaches methods; it is not clinical advice. Code, models and examples here are not validated medical devices and must not be used to make decisions about real patients without proper clinical validation, governance and any required regulatory approval. Examples use synthetic or openly licensed de-identified data only. Never paste identifiable patient information into public AI tools. Mentions of models, tools or vendors are for identification, not endorsement.