Skip to content

Drift

Drift tests detect distribution shift between the training data and the data the model is being validated on. They compare data distributions, not predictions — that is why they need X_train in the context and never call the model.

On the CLI, pass --train-data train.csv to enable them. From Python:

result = suite.run(model, X_val, y_val, X_train=X_train)

Without training data in the context they raise ValueError (reported as an ERROR, not a FAILED test).

Rule of thumb for PSI

PSI < 0.1: no significant shift · 0.1–0.25: moderate shift · > 0.25: major shift. The default max_psi=0.25 only fails on major shift; tighten it (e.g. 0.15) for sensitive models.

DataDriftTest

Assert the Population Stability Index (PSI) stays below a threshold for every checked column.

from modeltest.scenarios import DataDriftTest

DataDriftTest(feature_cols=["age", "income"], max_psi=0.15, n_bins=10)
Param Type Default Description
feature_cols list[str] | None None Columns to check; None checks all numeric columns of X_train.
max_psi float 0.25 Maximum tolerated PSI per column.
n_bins int 10 Quantile bins used to discretize each column.
- type: data_drift
  params: {features: [age, income], max_psi: 0.15}

Fails with detail like PSI for income = 0.4102 exceeds max_psi 0.15. A column missing from X_val also fails the test.

KSTest

Assert the two-sample Kolmogorov–Smirnov p-value stays above a threshold per column: a low p-value means the train and validation distributions of that column differ significantly.

from modeltest.scenarios import KSTest

KSTest(feature_cols=None, min_p_value=0.05)
Param Type Default Description
feature_cols list[str] | None None Columns to check; None checks all numeric columns of X_train.
min_p_value float 0.05 Minimum tolerated KS p-value per column.
- type: ks
  params: {columns: [age, income], min_p_value: 0.05}

PSI vs KS

PSI is bucketed and symmetric-friendly (works well on binned score distributions); KS is a formal hypothesis test sensitive anywhere the ECDFs diverge. Running both gives a cheap, complementary drift tripwire.