Skip to Content
Course content

213: Monitoring Model Drift in Production

Click on the "Edit" button in the top corner of the screen to edit your slide content.

Imagine you bought a high-end GPS map for a city in 2015. For a few years, it's perfect. You get everywhere on time. But then, the city builds a new highway system, closes a main bridge for permanent pedestrian use, and rezones the industrial district into luxury condos. The GPS isn't "broken"—the software is running exactly as it did on day one—but the world it was designed to navigate has changed. If you keep following those 2015 directions, you're going to end up driving into a river.

In R, model drift is that exact disconnect. Your model is the GPS, and the production data is the city. When the statistical properties of your input data shift (data drift) or the relationship between your features and the target variable changes (concept drift), your model's accuracy plummets even though the code hasn't changed a single line.

Spotting the Shift in Your Features

The first thing we need to do is realize that we can't just monitor the model's accuracy. Why? Because in production, you often don't get the "ground truth" (the actual result) for weeks or months. If you're predicting loan defaults, you won't know if you were wrong until the customer actually defaults. You need a leading indicator. That's where we monitor the distribution of the features themselves.

I usually lean on the Kolmogorov-Smirnov test in R for this. It's a non-parametric test that tells us if two samples come from the same distribution. If the distribution of a feature like monthly_spend in your training set differs significantly from the monthly_spend you're seeing in production today, your "map" is outdated.

# Let's say 'train_data' is what we used to build the model 
# and 'prod_data' is the last 30 days of live traffic.

# Check if the distribution of 'account_age' has shifted
drift_test <- ks.test(train_data$account_age, prod_data$account_age)

if(drift_test$p.value < 0.05) {
  message("Alert: Significant data drift detected in account_age!")
}

Operationalizing with Vetiver

Doing manual KS tests for twenty different features is a nightmare. I don't want to write a dozen if-statements every time I deploy. In the modern R ecosystem, we use the vetiver package. It's designed specifically to bridge the gap between a trained model and a production API.

vetiver allows you to version your models and, more importantly, it integrates with pins to track the data the model is seeing. Instead of guessing, you can log your production predictions and their inputs to a board. When you periodically compare these logs against your training baseline, you can visualize the drift. I find that plotting the density of a feature over time is far more convincing to stakeholders than a p-value; seeing a distribution curve physically slide to the left makes the need for retraining obvious.

When to Hit the Panic Button

Here is a bit of a professional opinion: not all drift requires a full retrain. Sometimes you have "seasonal drift." If you're predicting retail sales, your data will drift every November because of Black Friday. That's not a failure of the model; it's a characteristic of the business.

You have to distinguish between transient drift (temporary spikes) and structural drift (a fundamental change in consumer behavior). I always recommend setting up a "drift threshold." Don't retrain the moment a p-value hits 0.049. Instead, look for sustained drift over a window of time. If the distribution stays shifted for two weeks, that's when you pull the trigger on a new training run.




📋 Practical Task

Build a Feature Drift Detector for Customer Churn

You are maintaining a churn prediction model. You've noticed that the model's performance has dipped, and you suspect the avg_session_duration feature has drifted since the latest app update.

Your Task: Write an R script that performs the following:

  1. Create a synthetic training vector train_session with 1,000 values drawn from a normal distribution (mean = 120, sd = 20).
  2. Create a synthetic production vector prod_session with 1,000 values drawn from a normal distribution (mean = 105, sd = 25) to simulate a shift in user behavior.
  3. Use the ks.test() function to compare these two distributions.
  4. Write a conditional statement that prints "RETRAIN MODEL" if the p-value is less than 0.01, and "STABLE" otherwise.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.