Skip to main content
Fanout
Model Performance Monitoring
Curriculum overview

Machine Learning Operations (MLOps) · lesson 17/25

Model Performance Monitoring

Accuracy measured in a notebook describes a fixed dataset; production performance is a quantity that moves every day. Monitoring it means defining the metric that matters in business units, measuring it with the labels you actually receive, and knowing what to watch while those labels are missing. An aggregate score can hold steady while a segment collapses, so the unit of observation is a slice, not the whole.

The idea

Layer the metrics so a failure can be localized:

  • System: latency percentiles, throughput, error rate, queue depth, feature-store hit rate.
  • Model: score distribution, calibration, fraction of predictions above the decision threshold, feature-null rate.
  • Outcome: precision and recall at the operating threshold, conversion, revenue, fraud loss — whatever the model exists to move.

Three practices make the numbers trustworthy:

  • Slice everything. Report each metric per important segment (new versus returning users, region, device, model version). A global metric that is fine can hide a slice that is failing, because the slice is small or because changes in mix offset each other.
  • Compare like windows. A seven-day window against a ninety-day average mostly measures seasonality. Compare the same weekday and the same length, or model the seasonal baseline explicitly.
  • Use consistent label definitions. If the label pipeline changes the definition of a positive, the metric moves and the model did not.

Worked example

Illustrate with a constructed scenario, not a claim about a real system. A churn model's overall recall is unchanged this quarter, so nobody investigates. Slicing by tenure reveals that recall for customers under 30 days old fell sharply while the long-tenure segment improved, and the two effects cancel in the aggregate. The cause is upstream: an onboarding redesign changed what days_active counts, so the feature now means something different for new accounts than it did in training.

The fix is not a retrain by itself. Recompute the feature with the original definition, backfill history, verify the slice recovers on a held-out window, then consider whether the definition itself should be documented in the feature contract so the next redesign does not repeat the failure.

In code

from sklearn.metrics import precision_score, recall_score

def slice_report(y_true, y_pred, slices):
    report = {}
    for name, mask in slices.items():
        report[name] = {
            "n": int(mask.sum()),
            "precision": precision_score(y_true[mask], y_pred[mask], zero_division=0),
            "recall": recall_score(y_true[mask], y_pred[mask], zero_division=0),
        }
    return report

Check yourself

  1. Why should important slices be monitored separately from the global metric?
  2. What can you monitor about a scored model before any ground-truth labels arrive?
  3. What goes wrong when you compare a 7-day window against a 90-day average?

Key takeaways

  • Define the business metric and the decision-time proxy before launch, not after the first complaint.
  • Slice-level monitoring catches failures that the aggregate hides.
  • Compare like-for-like windows; seasonality and mix shifts are not model degradation.