The PSI is the credit-scoring industry's standard drift metric: bin a variable using the reference (training) distribution, then compare the share of the current population in each bin.
where and are the expected (reference) and actual (current) proportions in bin i.
Implement:
quantile_edges(reference, bins=10): the interior bin edges at the reference's quantiles 1/bins, 2/bins, … (bins - 1 edges)proportions(x, edges, eps=1e-4): the share of x in each bin (use np.searchsorted(edges, x, side='right') for bin indices), with each proportion floored at eps so the log is definedpsi(reference, current, bins=10)psi_status(value): "stable" below 0.1, "moderate" below 0.25, otherwise "shifted"