Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Drift along a time axis

The drift detector answers a narrower question than the breaks pass: given a column the caller declares as the time axis, do the relationships behind a numeric target change between the earliest period and later ones?

It engages only when the time axis is declared, with hints={"time": "<column>"}. The rows are cut into contiguous periods of roughly equal row counts along that axis. For each numeric target, the predictability screen’s gradient-boosting model is fitted on the earliest period alone, with the time column withheld from the predictors — a model that splits on the time axis itself routes every later period to one side by construction, which would read as maximal drift on stable data. Each later period is then scored against the reference period by routing both periods’ rows through the fitted trees: at every split, the two periods’ left/right counts form a 2x2 table, and the drift score is the mean chi-square across splits, weighted by each split feature’s share of the model’s total gain, so splits on features the model barely uses contribute almost nothing. Under no drift the score averages near 1.

the predictors of x drift over t: split-routing drift score reaches 343.0 in period 4 (2000 to 2499), against a no-drift scale of ~1
the predictors of y drift over t: split-routing drift score reaches 336.7 in period 4 (2000 to 2499), against a no-drift scale of ~1

The planted shift starts halfway through the series, at t = 2000. With eight periods of 500 rows, that is the boundary between period 3 and period 4. The evidence carries one entry per later period, so the onset is read directly from the table: scores sit near the no-drift scale of 1 before the shift and jump after it. concept_drift repeats the mean over only the splits that have a leaf child. Both sides of every comparison use the same row count (the smaller period’s), because the chi-square grows with the number of compared rows as well as with the size of the shift. A finding takes more than a large score. The maximum over periods must also beat a permutation null: the reference rows and every period’s compared rows are pooled and reassigned to a pseudo-reference group and pseudo-period groups of the original sizes, every period is rescored against the shared pseudo-reference, and the maximum is retaken — 16 replicates. The null prices the max-over-periods selection itself, including the fact that all periods share one reference (an atypical reference draw elevates every comparison at once, and the replicates reproduce that). The evidence carries the largest replicate maximum as null_max; a finding requires the real maximum to exceed it and to reach 5.0.

reference period: 0 to 499
reference rows: 500  reference R2: 0.994
1 500 to 999 drift: 1.03  concept: 1.24
2 1000 to 1499 drift: 0.72  concept: 0.73
3 1500 to 1999 drift: 0.79  concept: 0.51
4 2000 to 2499 drift: 336.71  concept: 316.32
5 2500 to 2999 drift: 336.71  concept: 316.32
6 3000 to 3499 drift: 336.71  concept: 316.32
7 3500 to 3999 drift: 336.71  concept: 316.32

Two controls. The same generator without the shift produces no drift finding, and the shifted frame without the time hint produces none either — the detector does not guess an axis.

stable, with hint: 0
shifted, no hint: 0

Limits

The score sees only the variables the reference-period model splits on. Drift confined to a variable the model does not use, or a change in the target’s own distribution with its predictors unchanged, does not register. The reference model must reach a holdout R2 of at least 0.2 on the reference period; a target with no learnable structure there is not scored. Periods with fewer than 100 compared rows record null scores rather than noisy ones.