Point anomaly vs change-point
A point anomaly is a transient - one day spikes, then the series returns to normal. A change-point is a sustained shift - the level, trend, or variance moves to a new regime and stays there. That difference matters: a z-score or isolation forest scores each day against a fixed picture of "normal," so once the new regime becomes the majority, the detector quietly accepts it. Time-series detectors watch the series evolve instead, and that is what catches the drift a point detector sleeps through.
Accumulate what a point detector misses 6 min live
CUSUM - the cumulative sum control chart (Page, 1954) - keeps a running total of how far each point sits above (or below) an expected level, minus a slack. A single small deviation barely moves it; a persistent drift piles up until the sum crosses a threshold and alarms. That is exactly the anomaly a per-point z-score cannot see: no one day is extreme, but together they have walked the series to a new level.
LiveHow tabular CUSUM works3 min▶
Work on a standardized residual (deseasonalize first, then scale robustly), then keep two running sums:
- High side -
S⁺ = max(0, S⁺ + x - k). It rewards deviations above a slackkand floors at zero, so noise cannot build it up. - Low side -
S⁻ = min(0, S⁻ + x + k). The mirror image for drops. - Alarm - when
S⁺crosses a thresholdh(orS⁻crosses-h). Reset to zero and keep scanning.
The slack k (often 0.5 sigma) sets how big a shift you care about; the threshold h trades detection speed against false alarms - the same precision/recall dial as always.
Reach for a library when it gets serious. ruptures (Truong et al.) offers Pelt, binary segmentation, and window-based change-point detection over multiple cost models, and Basseville & Nikiforov (1993) is the reference text for the theory. Build CUSUM once by hand to own the intuition, then lean on the library for multi-regime, multivariate work.
Predict the next value, flag the surprise 5 min live
The forecasting course ended by monitoring its own predictions - and that is a detector. Forecast each day one step ahead (seasonal-naive, or Holt-Winters from that course), then look at the residual: actual minus forecast. If the model already captures trend and weekly rhythm, the residuals are small and structureless - so a point that lands far outside their band is a genuine surprise, context already accounted for.
Self-studyWhy residuals, not raw values2 min read▶
Flagging raw values drowns you in false alarms: every weekend low and every trend high looks "extreme" against a flat mean. Residuals fix that by folding the known structure into the forecast:
- Trend and seasonality live in the forecast, so the residual is what the model could not explain.
- Set the band on a robust scale of the residuals - the median and MAD, not the mean and standard deviation - so a few big anomalies do not inflate the very band meant to catch them (the same trap as the z-score in b1).
- This is why a contextual anomaly - a weekday sitting at a weekend level - shows up here: it is normal in value but far from what the same weekday forecast expected.
CUSUM from scratch ★ 13 min · everyone builds
Deseasonalize the Lumen series, standardize the residual robustly, then run a tabular CUSUM by hand. It accumulates the sustained collective run that the per-point z-score in b1 was blind to.
Rebuild the labeled Lumen series (from b1) so the notebook runs standalone.
Remove the weekly context (subtract the weekday median) and standardize with median / MAD.
Walk the tabular CUSUM: two running sums, a slack k, a threshold h, reset on alarm.
Score precision, recall, and F1 against truth - note it catches the sustained run.
k and h, not by luck
Raise h and you get fewer, later, higher-confidence alarms; lower it and you catch smaller shifts sooner at the cost of false alarms. That is the precision/recall trade in two knobs - set it to the cost of a missed shift versus the cost of a muted analyst.
Forecast-residual detector ★ 9 min · build your own
Forecast each day one step ahead with a seasonal-naive model (today looks like the same weekday a week ago), then flag any actual whose residual falls outside a robust band. This is the forecasting course's monitoring loop turned into a detector - and because the forecast already knows the weekly context, it catches the contextual dip too.
Forecast one step ahead: s.shift(7) is the seasonal-naive prediction.
Compute residuals and a robust band (median ± a MAD multiple).
Flag actuals outside the band and score precision, recall, and F1 against truth.
This is the pattern most production monitoring actually uses. Forecast the metric, band the residual, alert on the breach - it is interpretable ("we expected 1,050 sessions, got 1,480"), it deseasonalizes for free, and it degrades gracefully when the model is wrong. The catch: a forecast-residual detector is only as honest as its band. Fit the band on a clean stretch of history, refresh it as the series drifts, and never let the anomalies you are hunting set the width.
Try it yourself - this week ◐ 30-45 min total
- Run the CUSUM detector and sweep the threshold
hfrom 3 to 6. Watch precision rise and recall fall - plot the trade. - Turn off the deseasonalize step and rerun CUSUM. Count the extra false alarms the weekly rhythm creates.
- Compare the CUSUM flags with the forecast-residual flags. Which detector catches the collective run, and which catches the contextual dip?
- Swap the seasonal-naive forecast for
statsmodelsExponentialSmoothing (Holt-Winters) and see whether the tighter forecast sharpens or muddies the residuals. - Optional: skim the
rupturesdocs and run Pelt on the same series - compare its change-points to your CUSUM alarms.
Sources covered (cited)
Taught from the change-detection canon, handed off from the forecasting course. This session covers:
ruptures as the practical libraryThree questions before you go 🎯 ◐ 90 seconds
1 · What separates a change-point from a point anomaly?
The point anomaly is one-off and the series recovers; the change-point moves the level, trend, or variance and stays there - which a fixed-picture point detector eventually accepts.
2 · Why does CUSUM catch drifts a per-point z-score misses?
CUSUM keeps a running sum. Individually harmless deviations in the same direction add up; a point detector, scoring each day alone, never sees the accumulation.
3 · In a forecast-residual detector, why set the band with median and MAD?
Mean and standard deviation are dragged upward by the outliers you are hunting, widening the band until it misses them. Median and MAD resist that - the same lesson as the z-score trap in b1.