The Silent Failure Mode of Machine Learning
Unlike an API that returns HTTP 500 when a database connection dies, a machine learning model will happily accept drifted input distributions and output confident nonsense. If consumer behavior shifts, if a hospital purchases new fundus imaging cameras with slightly different color saturation, or if macroeconomic factors shift stock volatility, your model's accuracy deteriorates while CPU and latency metrics remain green.
Calculating Population Stability Index (PSI) in Python
The Population Stability Index (PSI) is an industry-standard metric for measuring divergence between a reference (baseline/training) distribution and an active production distribution:
import numpy as np
def calculate_psi(baseline: np.ndarray, current: np.ndarray, num_bins: int = 10) -> float:
# Generate quantile bins from baseline distribution
percentiles = np.linspace(0, 100, num_bins + 1)
bin_edges = np.percentile(baseline, percentiles)
bin_edges[0] -= 1e-5
bin_edges[-1] += 1e-5
baseline_counts, _ = np.histogram(baseline, bins=bin_edges)
current_counts, _ = np.histogram(current, bins=bin_edges)
baseline_pct = np.clip(baseline_counts / len(baseline), 1e-4, 1.0)
current_pct = np.clip(current_counts / len(current), 1e-4, 1.0)
# PSI Formula
psi_value = np.sum((current_pct - baseline_pct) * np.log(current_pct / baseline_pct))
return float(psi_value)
# Benchmarks:
# PSI < 0.10: Stable
# 0.10 <= PSI < 0.25: Moderate drift
# PSI >= 0.25: Severe drift