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.

Case study: one expansion behind three drift findings

A delivery log has one row per order: the trip distance, the delivery time, the fuel used, the number of calls to the customer, the rainfall, and the parcel weight. Operations wants to know whether anything changed midway through the log’s eight months. The drift detector compares the earliest period against each later one for every numeric target, using a model of that target fitted on the earliest period alone.

The fixture plants exactly one change: halfway through the log (row 2400 of 4800), the service area expands and a far zone joins the zone mix, so the distance distribution shifts. delivery_min and fuel_l are computed from distance; calls, rain_mm, and weight_kg have no time structure at all and act as controls.

Read the drift findings first:

the predictors of distance_km drift over t: split-routing drift score reaches 55.7 in period 5 (3000 to 3599), against a no-drift scale of ~1
the predictors of fuel_l drift over t: split-routing drift score reaches 47.9 in period 5 (3000 to 3599), against a no-drift scale of ~1
the predictors of delivery_min drift over t: split-routing drift score reaches 47.5 in period 4 (2400 to 2999), against a no-drift scale of ~1
3 drift findings

One onset, shared by all three findings

The claims name the period where each score peaks, which is not where the change starts — the peak is wherever the already-shifted periods happen to score highest. The onset is read from the periods evidence: one entry per later period with its drift score. For delivery_min:

null_max: 2.3
period 1: 600 to 1199  drift 0.5
period 2: 1200 to 1799  drift 1.4
period 3: 1800 to 2399  drift 0.8
period 4: 2400 to 2999  drift 47.5
period 5: 3000 to 3599  drift 47.4
period 6: 3600 to 4199  drift 40.6
period 7: 4200 to 4799  drift 44.9

Reading the three findings as one event

Scores sit at the no-drift scale (0.5–1.6) through period 3 and jump to 40–56 from period 4 — the period that starts at row 2400, where the expansion was planted. All three targets share that onset, and the three are not independent: fuel and delivery time are both computed from distance, so when the distance distribution moves, the models of all three targets route later rows differently. distance_km firing on its own model is the tell that the carrier is the input distribution itself, not a changed relationship. The controls — calls, rainfall, weight — produce no drift findings, and each finding’s null_max (2.3–3.2 across the three) sits far below its maximum score, so the permutation gate is not what separates signal from noise here.

The direct check agrees: mean distance by period block jumps at the same boundary and stays at the new level.

┌────────┬─────────────┐
│ period ┆ distance_km │
╞════════╪═════════════╡
│ 0      ┆ 3.74        │
│ 1      ┆ 3.71        │
│ 2      ┆ 3.83        │
│ 3      ┆ 3.94        │
│ 4      ┆ 9.5         │
│ 5      ┆ 9.43        │
│ 6      ┆ 9.09        │
│ 7      ┆ 9.35        │
└────────┴─────────────┘

What would change the reading: if delivery_min fired while distance_km stayed quiet, the relationship between distance and delivery time itself would have moved — a different operational story (traffic, a new routing policy) than an input distribution that expanded. The detector cannot make that distinction from scores alone; the pattern of which targets fire, and the shared onset in the periods evidence, is what carries it.