Lesson 40 of 40

Chapter 40 — Monitoring a Supervised Model

Learning objectives

  • Explain why a model that performed well at deployment can become less reliable over time.
  • Design input-data checks for schema, missingness, ranges, categories, and distribution changes.
  • Monitor prediction volume, class balance, confidence, extreme outputs, and rejection or review rates.
  • Track classification or regression performance when delayed ground-truth labels become available.
  • Define retraining triggers, review responsibilities, rollback criteria, and monitoring records.
  • Produce a practical monitoring plan for a final supervised-learning model.

Chapter focus

Deployment is not the end of the machine-learning workflow. Monitoring asks whether the incoming data, the model outputs, and eventually the measured outcomes still resemble the conditions under which the model was validated.

 

40.1 Why model performance changes

A supervised model learns relationships from historical data. Those relationships can become less useful when the environment changes. Some changes are gradual, some are abrupt, and some are caused by software or data-pipeline failures rather than by the real world itself.

Source of changeWhat may happenMonitoring clue
Data distribution changesFeature values or category proportions move away from the training distribution.Range checks, missingness, category frequencies, drift statistics.
User behavior changesPeople respond differently because preferences, incentives, or workflows change.Prediction mix changes; later performance declines.
New productsNew product families create feature combinations not represented during training.New categories, unusual ranges, low-confidence predictions.
Economic changesPrices, demand, risk, and customer behavior may shift together.Broad feature drift and subgroup performance changes.
Sensor changesReplacement hardware or calibration changes alter measurement distributions.Step changes in means, ranges, or missing-value patterns.
Data pipeline errorsA join, parser, unit conversion, or column mapping fails.Schema violations, impossible values, sudden missingness.
Concept driftThe relationship between X and y changes even if X itself looks familiar.Input checks may look normal while labeled performance degrades.

 

Important distinction

Data drift means the distribution of inputs changes. Concept drift means the relationship between inputs and the target changes. Input monitoring can detect the first directly; the second usually requires labels or a reliable proxy for performance.

 

Monitoring time horizons

A useful monitoring system compares several horizons rather than one fixed window. For example, the last day may reveal pipeline failures, the last week may reveal operational changes, and the last month may reveal slower behavioral drift.

WindowTypical purposeExample question
Near real time / hourlyOperational healthDid a source stop sending data?
DailyFast distribution shiftsDid missingness or prediction volume jump today?
WeeklyBehavior and quality trendsIs confidence falling across several days?
Monthly / quarterlyLonger-term stabilityIs performance deteriorating enough to require retraining?

 

40.2 Input monitoring

Input monitoring checks whether the model is receiving data in the form and range it expects. These checks are available before labels arrive, so they are often the first line of defense in production.

  • Missing-value rate: compare current missingness with a training or validation reference profile.
  • Feature ranges: detect impossible, extreme, or newly observed values.
  • Category frequencies: detect new categories and large changes in category proportions.
  • Data types: confirm that numeric, categorical, Boolean, and datetime fields have not changed representation.
  • Schema changes: detect missing, extra, renamed, or reordered fields where ordering matters.
  • Distribution changes: compare reference and current distributions using descriptive or statistical measures.

Reference profile

Monitoring requires a baseline. Save a reference profile from the approved training or validation data at model-release time. The profile should contain the expected schema and simple descriptive statistics that can be compared with future batches.

Python example — build a compact reference profile

import pandas as pd

numeric = ["age""income""transactions_30d"]
categorical = ["region""product_type"]

reference = {
     "columns": X_train.columns.tolist(),
     "dtypes": X_train.dtypes.astype(str).to_dict(),
     "missing_rate": X_train.isna().mean().to_dict(),
     "numeric_mean": X_train[numeric].mean().to_dict(),
     "numeric_std": X_train[numeric].std().to_dict(),
     "numeric_min": X_train[numeric].min().to_dict(),
     "numeric_max": X_train[numeric].max().to_dict(),
     "category_frequency": {
         c: X_train[c].value_counts(normalize=True).to_dict()
         forin categorical
     },
}

 

 

Schema and missingness checks

Python example — validate columns, dtypes, and missing-value changes

def input_health_report(frame, reference, missing_tolerance=0.05):
     expected = set(reference["columns"])
     received = set(frame.columns)

     missing_columns = sorted(expected - received)
     extra_columns = sorted(received - expected)
     current_missing = frame.isna().mean()

     missing_alerts = {}
     for feature, base_rate in reference["missing_rate"].items():
         if feature in frame:
            delta = current_missing[feature] - base_rate
            if delta > missing_tolerance:
                missing_alerts[feature] = round(float(delta), 4)

     return {
         "missing_columns": missing_columns,
         "extra_columns": extra_columns,
         "missing_rate_increase": missing_alerts,
     }

 

 

Simple distribution monitoring

Not every monitoring system needs a complex drift library. A transparent first version can track standardized mean movement for numeric variables and absolute frequency changes for categorical variables. More advanced systems may add PSI, KS tests, Jensen-Shannon divergence, or model-based drift detectors.

Standardized mean shift = |current mean - reference mean| / reference standard deviation

 

Python example — numeric mean-shift report

def numeric_shift_report(frame, reference, features, alert_at=0.5):
     rows = []
     for feature in features:
         current_mean = frame[feature].mean()
         base_mean = reference["numeric_mean"][feature]
         base_std = reference["numeric_std"][feature]
         shift = abs(current_mean - base_mean) / max(base_std, 1e-12)
         rows.append({
            "feature": feature,
            "standardized_mean_shift": shift,
            "alert": shift >= alert_at,
         })
     return pd.DataFrame(rows).sort_values(
         "standardized_mean_shift", ascending=False
     )

 

 

Caution

A drift alert does not automatically mean the model is wrong. It means current data differ from the reference and deserve investigation. Thresholds should be calibrated from historical variation and operational risk, not copied blindly from a generic example.

 

40.3 Prediction monitoring

Prediction monitoring observes the model outputs even when ground-truth labels are not yet available. Sudden changes can reveal upstream data problems, new populations, threshold effects, or a genuine change in demand.

SignalClassification exampleRegression example
Prediction frequencyNumber of scores per hour/day.Number of forecasts per hour/day.
Output distributionFraction predicted positive/negative.Mean, median, and spread of predictions.
Confidence distributionHistogram of predicted probabilities or margins.Uncertainty interval width if available.
Extreme predictionsProbabilities near 0 or 1.Predictions near or beyond plausible limits.
Rejection / review rateFraction sent to human review or abstained.Fraction outside safety checks or requiring review.

 

Python example — monitor classification outputs

import numpy as np
import pandas as pd

probability = final_pipeline.predict_proba(X_batch)[:, 1]
prediction = (probability >= decision_threshold).astype(int)
confidence = np.maximum(probability, 1 - probability)

prediction_report = {
     "n_predictions"len(prediction),
     "positive_rate"float(prediction.mean()),
     "mean_probability"float(probability.mean()),
     "low_confidence_rate"float((confidence < 0.60).mean()),
     "very_high_probability_rate"float((probability > 0.95).mean()),
}

print(pd.Series(prediction_report))

 

 

Abstention and review monitoring

If the application can abstain or request human review, the review rate becomes a first-class operational metric. A rising review rate may indicate safer behavior under uncertainty, but it may also overwhelm the team responsible for manual decisions.

Python example — confidence-based review flag

lower, upper = 0.400.60
review = (probability >= lower) & (probability <= upper)

review_rate = review.mean()
auto_decision_rate = 1.0 - review_rate

print(f"Review rate: {review_rate:.3f}")
print(f"Automatic decision rate: {auto_decision_rate:.3f}")

 

 

40.4 Performance monitoring

True model performance can be measured only when trustworthy outcomes arrive. Labels may be immediate, delayed by days or months, incomplete, or biased toward cases that receive follow-up. Monitoring design must document this label process before interpreting trends.

Classification performance over time

  • Accuracy and F1 over time, using a fixed evaluation definition.
  • Precision and recall when false-positive and false-negative costs differ.
  • ROC AUC or precision-recall metrics when probability ranking matters.
  • Performance by subgroup, source, region, device, or other operational slice.
  • Calibration changes: whether predicted probabilities still match observed frequencies.
  • Threshold effectiveness: whether the chosen operating point still satisfies operational objectives.

Python example — classification metrics by time period

from sklearn.metrics import accuracy_score, f1_score, precision_score, recall_score

def classification_metrics(group):
     y_true = group["actual"]
     y_pred = group["prediction"]
     return pd.Series({
         "n"len(group),
         "accuracy": accuracy_score(y_true, y_pred),
         "precision": precision_score(y_true, y_pred, zero_division=0),
         "recall": recall_score(y_true, y_pred, zero_division=0),
         "f1": f1_score(y_true, y_pred, zero_division=0),
     })

weekly = scored_with_labels.groupby("week").apply(
     classification_metrics, include_groups=False
)
print(weekly)

 

 

Regression performance over time

Python example — MAE and RMSE by month

from sklearn.metrics import mean_absolute_error, mean_squared_error

def regression_metrics(group):
     y_true = group["actual"]
     y_pred = group["prediction"]
     return pd.Series({
         "n"len(group),
         "mae": mean_absolute_error(y_true, y_pred),
         "rmse": mean_squared_error(y_true, y_pred) ** 0.5,
         "mean_error": (y_true - y_pred).mean(),
     })

monthly = scored_with_labels.groupby("month").apply(
     regression_metrics, include_groups=False
)
print(monthly)

 

 

Subgroup and calibration monitoring

Aggregate metrics can hide local deterioration. A monitoring report should therefore repeat the important error metrics by relevant operational slices. For probabilistic classifiers, calibration should also be monitored because a model can maintain a similar AUC while its probabilities become systematically too high or too low.

Python example — subgroup classification report

def subgroup_report(frame, group_column):
     rows = []
     for group_name, g in frame.groupby(group_column):
         y_true = g["actual"]
         y_pred = g["prediction"]
         rows.append({
            "group": group_name,
            "n"len(g),
            "f1": f1_score(y_true, y_pred, zero_division=0),
            "recall": recall_score(y_true, y_pred, zero_division=0),
         })
     return pd.DataFrame(rows).sort_values("f1")

print(subgroup_report(scored_with_labels, "region"))

 

 

Label delay matters

A dashboard that shows yesterday's input drift next to performance labels that describe customers from three months ago can be misleading. Every monitored metric should state the event time, prediction time, and label-availability time it represents.

 

40.5 Retraining strategy

Retraining should be a controlled model-change process, not an automatic reaction to every alert. A monitoring plan defines who investigates, what evidence is required, how a replacement model is validated, and how the organization can roll back if the new model fails.

StrategyTriggerAdvantagesRisks / cautions
Scheduled retrainingFixed calendar interval.Simple planning; predictable governance.May retrain when unnecessary or react too slowly to abrupt change.
Performance-triggeredMetric crosses a predefined action threshold.Directly tied to measured usefulness.Requires reliable and sufficiently timely labels.
Data-volume-triggeredEnough new labeled observations accumulate.Ensures a meaningful amount of new evidence.Volume alone does not prove the environment changed.
Manual reviewAnalyst or domain team decides after investigation.Allows context and root-cause analysis.Slower and depends on clear ownership.
RollbackNew model violates safety/performance criteria.Restores a previously approved artifact quickly.Requires preserved artifacts, data contracts, and deployment compatibility.

 

A controlled retraining workflow

  1. Detect an alert or scheduled review event.
  2. Diagnose whether the cause is data quality, drift, label problems, or genuine concept change.
  3. Create a refreshed candidate dataset using an explicit cutoff date and target definition.
  4. Retrain candidate models under the approved validation protocol.
  5. Compare the candidate with the current production model using the same metrics and slices.
  6. Approve, version, and deploy only if acceptance criteria are satisfied.
  7. Monitor the new model closely and retain a tested rollback path.

Do not retrain blindly

If the root cause is a broken unit conversion, missing source, or changed label definition, retraining on corrupted data can make the problem worse. Fix the data-generating process first, then reassess whether retraining is still necessary.

 

Monitoring ownership and records

ItemWhat to record
Model identityModel name, artifact version, deployment date, decision threshold.
Reference dataDataset version and period used to create monitoring baselines.
Metric definitionFormula, grouping window, exclusions, and label delay.
Alert ruleWarning/action threshold, minimum sample size, and persistence rule.
OwnerTeam or person responsible for investigation and response.
Action historyAlert date, diagnosis, mitigation, retraining decision, rollback if used.

 

Practical activity — Design a monitoring plan for the final model

Objective: create a monitoring specification that could be handed to an engineering or operations team after deployment. The activity uses a classification example, but the same structure can be adapted to regression.

Scenario

Assume the final model predicts customer churn each day. The application receives customer behavior data, produces a churn probability, applies a fixed threshold selected before final test evaluation, and sends low-confidence cases to human review. Confirmed churn labels arrive approximately 30 days later.

Step 1 — Create a synthetic monitoring stream

Python lab — create reference and current batches

import numpy as np
import pandas as pd

rng = np.random.default_rng(42)
= 1500

reference_batch = pd.DataFrame({
     "tenure_months": rng.normal(3212, n).clip(172),
     "monthly_spend": rng.normal(6518, n).clip(5180),
     "tickets_30d": rng.poisson(1.2, n),
     "region": rng.choice(["North""South""West"], n, p=[0.40.350.25]),
})

current_batch = reference_batch.copy()
current_batch["monthly_spend"*= 1.12
current_batch.loc[rng.random(n) < 0.08"tickets_30d"= np.nan

 

 

Step 2 — Build a compact reference profile

Python lab — reference means, standard deviations, and missingness

numeric = ["tenure_months""monthly_spend""tickets_30d"]

baseline = {
     "columns": reference_batch.columns.tolist(),
     "missing_rate": reference_batch.isna().mean().to_dict(),
     "numeric_mean": reference_batch[numeric].mean().to_dict(),
     "numeric_std": reference_batch[numeric].std().to_dict(),
     "region_frequency": reference_batch["region"].value_counts(normalize=True).to_dict(),
}

print(pd.Series(baseline["numeric_mean"]))

 

 

Step 3 — Monitor input health

Python lab — compare current input with the baseline

input_rows = []
for feature in numeric:
     base_mean = baseline["numeric_mean"][feature]
     base_std = baseline["numeric_std"][feature]
     current_mean = current_batch[feature].mean()
     shift = abs(current_mean - base_mean) / max(base_std, 1e-12)
     missing_change = (
         current_batch[feature].isna().mean()
         - baseline["missing_rate"][feature]
     )
     input_rows.append({
         "feature": feature,
         "mean_shift_sd": shift,
         "missing_change": missing_change,
     })

print(pd.DataFrame(input_rows))

 

 

Step 4 — Monitor predictions and confidence

Use your final trained pipeline if available. If the class project is not yet deployed, simulate stored probabilities so that the monitoring logic can still be implemented and tested.

Python lab — prediction-distribution report

# Replace this line with final_pipeline.predict_proba(...) in your project.
probability = np.clip(rng.beta(2.25.0, n), 01)
decision_threshold = 0.45
prediction = (probability >= decision_threshold).astype(int)
confidence = np.maximum(probability, 1 - probability)
review = confidence < 0.60

prediction_summary = pd.Series({
     "n": n,
     "positive_rate": prediction.mean(),
     "mean_probability": probability.mean(),
     "low_confidence_rate": review.mean(),
     "p95_probability": np.quantile(probability, 0.95),
})
print(prediction_summary)

 

 

Step 5 — Add delayed performance monitoring

Python lab — weekly F1 and recall once labels arrive

from sklearn.metrics import f1_score, recall_score

monitor = pd.DataFrame({
     "week": np.repeat(np.arange(17), n // 6)[:n],
     "probability": probability[:n],
})
monitor["prediction"= (monitor["probability">= decision_threshold).astype(int)

# In production, replace this simulated target with confirmed delayed labels.
monitor["actual"= rng.binomial(1, monitor["probability"].clip(0.050.80))

weekly = monitor.groupby("week").apply(
     lambda g: pd.Series({
         "n"len(g),
         "f1": f1_score(g["actual"], g["prediction"], zero_division=0),
         "recall": recall_score(g["actual"], g["prediction"], zero_division=0),
     }),
     include_groups=False,
)
print(weekly)

 

 

Step 6 — Write alert rules as an engineering specification

AreaMetricBaseline / comparisonExample action ruleOwner / action
InputMissing rateRelease reference profileInvestigate if increase persists for 2 daily windows.Data team validates source and parser.
InputNumeric driftReference mean/std or full distributionReview if standardized mean shift exceeds calibrated tolerance.ML team checks product/behavior change.
PredictionPositive rateRecent approved operating rangeInvestigate abrupt or sustained change.ML + business owner assess demand and threshold.
PredictionLow-confidence rateRelease and recent historyReview capacity if rate rises materially.Operations checks review queue.
PerformanceF1 / recallFinal-test and recent production baselineEscalate after sufficient labeled sample and persistent degradation.Model owner opens retraining review.
PerformanceSubgroup metricApproved subgroup baselineInvestigate meaningful, persistent gap with adequate sample size.Model owner + domain reviewer.

 

Step 7 — Define the retraining and rollback policy

  • State whether retraining is scheduled, trigger-based, data-volume-based, manual, or a combination.
  • Specify the minimum amount and recency of labeled data required before retraining.
  • Keep the final-test-equivalent acceptance criteria for any replacement model.
  • Preserve the current approved artifact until the replacement is validated and deployable.
  • Define rollback conditions and verify that the previous artifact remains compatible with the serving system.

Student deliverable — monitoring plan

SectionRequired content
Model and use caseModel/version, target, users, prediction frequency, decision threshold.
Data inputsExpected schema, sources, ranges, categories, missingness, monitoring windows.
Prediction monitoringVolume, output distribution, confidence, review/rejection rate, extremes.
Performance monitoringMetrics, label delay, subgroup views, calibration or residual checks.
AlertsWarning/action levels, minimum sample size, persistence rule, responsible owner.
RetrainingTrigger type, validation protocol, approval criteria, deployment process.
RollbackPrevious approved artifact, rollback trigger, restoration test.
DocumentationDashboard/report frequency, incident record, change log, review cadence.

 

Discussion questions

1.  Which monitored signals can be computed immediately, and which require delayed labels?

2.  What input change would represent a harmless business change rather than a model failure?

3.  How will you choose alert thresholds without creating excessive false alarms?

4.  How much labeled evidence is required before declaring that performance has degraded?

5.  Which subgroup or operational slices are essential for your use case?

6.  What conditions should cause retraining, and what conditions should cause rollback instead?

Chapter summary

ConceptKey takeaway
Model changeProduction environments evolve through data drift, behavior change, pipeline failures, and concept drift.
Input monitoringTrack schema, dtypes, missingness, ranges, categories, and distribution changes before labels arrive.
Prediction monitoringTrack volume, output mix, confidence, extremes, and review/rejection rates.
Performance monitoringWhen labels arrive, track task metrics over time and by important slices.
Retraining / rollbackUse evidence-based retraining and keep a known-good artifact with a tested restoration path.
Train a Supervised Machine Learning Model
1 Chapter 1 — Introduction to Machine Learning 2 Chapter 2 — Understanding Supervised Learning 3 Chapter 3 — The Complete Supervised Learning Workflow 4 Chapter 4 — Defining the Machine Learning Problem 5 Chapter 5 — Loading and Inspecting Data 6 Chapter 6 — Exploratory Data Analysis 7 Chapter 7 — Cleaning the Dataset 8 Chapter 8 — Feature and Target Preparation 9 Chapter 9 — Splitting the Dataset Correctly 10 Chapter 10 — Numerical Feature Preprocessing 11 Chapter 11 — Encoding Categorical Features 12 Chapter 12 — Preprocessing Pipelines 13 Chapter 13 — Baseline Models 14 Chapter 14 — Logistic Regression 15 Chapter 15 — K-Nearest Neighbors Classification 16 Chapter 16 — Decision Tree Classification 17 Chapter 17 — Ensemble Classification Models 18 Chapter 18 — Support Vector Machines 19 Chapter 19 — Linear Regression 20 Chapter 20 — Regularized Regression 21 Chapter 21 — Tree-Based Regression 22 Chapter 22 — Confusion Matrix and Basic Metrics 23 Chapter 23 — Probability-Based Classification Evaluation 24 Chapter 24 — Regression Metrics 25 Chapter 25 — Residual Analysis 26 Chapter 26 — Underfitting and Overfitting 27 Chapter 27 — Cross-Validation 28 Chapter 28 — Feature Engineering 29 Chapter 29 — Feature Selection 30 Chapter 30 — Hyperparameter Tuning 31 Chapter 31 — Handling Imbalanced Classification 32 Chapter 32 — Designing a Fair Model Comparison 33 Chapter 33 — Final Test Evaluation 34 Chapter 34 — Global Model Interpretation 35 Chapter 35 — Local Prediction Explanation 36 Chapter 36 — Error Analysis and Robustness 37 Chapter 37 — Fairness and Ethical Considerations 38 Chapter 38 — Model Persistence 39 Chapter 39 — Building a Basic Prediction Application 40 Chapter 40 — Monitoring a Supervised Model