Time Series Anomaly Detection
Point/contextual/collective anomalies, CUSUM, STL residuals, LSTM autoencoders, adaptive thresholds
Time series anomaly detection fails in production for one specific reason more than any other: teams apply a threshold to the raw series instead of the residuals of a properly specified seasonal and trend model. An API error rate of 10,000 per minute is normal during peak traffic and anomalous at 3am — but a static threshold treats both identically. The raw series conflates seasonality, trend, and anomaly signal into a single number; a threshold on raw values fires whenever any component is high, including seasonality that's entirely expected. Decompose first, threshold on the residuals, and nearly all seasonality-driven false positives disappear. The quality ceiling for any anomaly detector is the quality of its baseline model — the residuals are only as clean as the decomposition.
Key points
- Applying a static threshold to a seasonal series produces false positives every time the seasonal component peaks — not because anything unusual happened, but because the underlying cycle reached its expected high. Decompose Y_t = T_t + S_t + R_t, then threshold R_t. Point anomaly: |R_t| > k·σ_R where σ_R is an IQR-based robust standard deviation and k=3-4. The decomposition removes expected variation; the threshold detects unexpected deviation. This single change eliminates the majority of seasonality-driven false positives in most production monitoring systems.
- Three anomaly types require different detection strategies. Point anomalies: a single observation far from expected (latency spike, sensor error). Contextual anomalies: a value normal in one context but anomalous in another — 500 sales on a random Tuesday versus 500 sales on Black Friday (should be 50,000). Collective anomalies: a sequence of individually normal observations that are jointly anomalous — 5 days of conversion rate 1% below normal, each individually within tolerance but collectively a significant degradation. Each type requires a different detection approach.
- CUSUM (Cumulative Sum Control Chart): C_t = max(0, C_{t-1} + (Y_t − μ₀ − k)). Alert when C_t > h. Directional — it accumulates evidence of sustained shift rather than reacting to single spikes. This makes CUSUM naturally suited for detecting collective anomalies (sustained shifts) and resistant to false positives from individual noisy observations. Requires specifying μ₀ and k — doesn't adapt to non-stationary baselines or seasonality without preprocessing (decompose first, then apply CUSUM to residuals).
- Isolation Forest for time series requires careful feature engineering. Applied to raw values, it ignores temporal structure entirely — it doesn't know that observation 100 follows observation 99. The correct input is a feature matrix: lag values [Y_{t-1}, Y_{t-2}, ...], rolling mean, rolling std, time-of-day, day-of-week. Without lag features, Isolation Forest is a point anomaly detector with no temporal awareness. It also cannot detect collective anomalies without explicit sliding window features encoding the joint distribution of a sequence.
- LSTM Autoencoders encode a time window and decode it back, using reconstruction error as the anomaly score. Trained on normal data only. High reconstruction error = the window is unusual relative to training distribution. The production problem is threshold calibration: the reconstruction error distribution shifts as the system drifts (concept drift), so a static threshold set at training time produces increasing false positives over time. Use a rolling calibration window — 99th percentile of reconstruction error over the past 7-14 days as the threshold, updated daily.
- Adaptive thresholds are necessary when variance is non-constant, when the series has multiple operating modes, or when you need to directly control the alert rate. Static 3-sigma fails on all three counts. EWMA control charts adapt to recent variance. Quantile regression estimates conditional quantiles as functions of time features (capturing time-varying variance). Conformal prediction provides coverage-guaranteed anomaly scores without distributional assumptions — the alert fires when the score falls in the top α fraction of calibration set scores, guaranteeing at most α false positive rate by construction.
- Root cause vs symptom: a single upstream failure propagates through a dependency graph and produces correlated anomalies across dozens of downstream metrics simultaneously, flooding the alert queue. A DB failure causes API latency, cache miss rate, and error rate to all spike within seconds. Alert flooding without root cause identification means incident responders chase symptoms while the root cause persists. Multi-variate anomaly detection finds correlated joint anomalies; causal graph traversal identifies whether the anomaly originated upstream or is local. Alert correlation groups alerts firing within the same time window into a single incident.
- Evaluation when labels are scarce: PR-AUC (precision-recall) beats ROC-AUC for imbalanced anomaly detection — imbalance is extreme (1 anomaly per 1000 normal observations), so ROC-AUC is dominated by the large number of true negatives. NAB (Numenta Anomaly Benchmark) score rewards early detection within a window before impact — detection two hours late is still valuable, just less so than detection immediately. Precision@k (fraction of top-k flagged events that are true anomalies) is practical when operators review top-ranked alerts. When labels cover only a small subset of a much larger population (50 of 10,000 sensors), evaluation can't stop there: check that the labeled subset is representative of the rest (similar sensor types, deployment conditions, failure modes) before trusting it to generalize; inject synthetic anomalies into the unlabeled sensors to get a proxy precision/recall reading where no real labels exist; monitor alert-rate drift over time as an unsupervised health check — a sudden change in firing rate with no matching real-world event usually means the model or data distribution moved, not that anomalies increased; and route a sample of unlabeled-sensor alerts to human reviewers to estimate live precision directly.
Nearly all production false-positive problems in time series anomaly detection trace back to applying a threshold to the raw series instead of the residuals of a properly specified seasonal+trend model. The decompose-first, threshold-on-residuals pattern eliminates seasonality-driven false positives immediately. The second most important insight is distinguishing root causes from downstream symptoms via causal graph traversal: a single upstream failure floods the alert queue with correlated alerts across dozens of metrics, and incident response fails when teams chase symptoms while the root cause persists.
Recap
- #1 production failure: thresholding the raw series instead of decomposition residuals → seasonal false positives.
- Decompose `Y=T+S+R`, threshold R_t (|R|>k·σ, IQR-based, k=3-4) — kills seasonality-driven alerts.
- Three types: point (single spike), contextual (500 sales normal Tue vs Black Friday), collective (sustained drift).
- CUSUM accumulates evidence of sustained shift — good for collective anomalies, resistant to single spikes.
- LSTM autoencoder: reconstruction error as score, trained on normal data; needs rolling threshold recalibration (concept drift).
- Adaptive thresholds (EWMA, quantile regression, conformal) beat static 3-sigma; conformal guarantees ≤α FPR.
- Root cause vs symptom: one upstream failure floods alerts across metrics — trace causal graph, don't chase symptoms.
- Imbalanced eval: PR-AUC beats ROC-AUC; NAB rewards early detection.
Check your understanding
Q1. Your 3-sigma threshold on raw API error rate generates 200 false-positive alerts per day from seasonality. Which TWO fixes are correct?
- A) Decompose the series with STL first, compute residuals R_t=Y_t−T_t−S_t, and threshold on those residuals rather than the raw series — this removes seasonality-driven false positives directly at the source.
- B) An EWMA control chart applied to the residuals, with the alert rate calibrated via a rolling percentile of recent residual magnitude, adapts the threshold as normal behaviour gradually drifts over time.
- C) Increase the threshold from 3-sigma to 5-sigma across the raw series; the higher threshold alone will reduce false positives caused by seasonal peaks without requiring any decomposition step at all.
- D) Apply separate 3-sigma thresholds for each hour and day of week directly on the raw series; stratifying by calendar period alone fully substitutes for an explicit trend-and-seasonal decomposition model.
Q2. You use an LSTM autoencoder for multivariate anomaly detection on 50 metrics. The reconstruction error correctly identifies an outage on day 15 of deployment, but by day 90 the false positive rate has tripled. What happened and how do you fix it?
- A) The LSTM autoencoder has overfit specifically to the day-15 outage pattern and now flags any deviation from that exact pattern as anomalous; retrain on a dataset that fully excludes the day-15 outage window.
- B) The 50-metric input dimensionality causes the autoencoder to gradually memorise normal patterns rather than generalise; apply PCA to reduce to 10 components before feeding the data into the autoencoder.
- C) The LSTM hidden state becomes numerically saturated after 90 days of continuous streaming inference; reset the hidden state every 7 days and the false positive rate will return to its original baseline level.
- D) Concept drift: normal behaviour shifted but the autoencoder still uses day-0 distribution. Fix: periodic retraining on a rolling 30-60 day window, plus an adaptive threshold at the 99th percentile of recent errors.
Q3. You detect a latency spike anomaly in your API service. Your colleague says it is a "real anomaly." You say it is a downstream symptom. How do you distinguish, and what are the implications for incident response?
- A) Check whether the API latency anomaly score exceeds the 99th versus 95th percentile threshold; a score above the 99th percentile indicates a root cause, while a 95th-percentile score indicates a downstream symptom.
- B) Run a Granger causality test from upstream metrics to API latency; if the test is significant at p < 0.05, the API latency is confirmed to be a downstream symptom driven purely by the upstream metric.
- C) Check temporal order (did DB anomaly precede latency?), trace the call graph, cross-correlate anomaly times for earliest onset. Mitigating the symptom causes incorrect incident response — build a causal graph.
- D) Always treat the first anomaly detected in the alert queue as the root cause regardless of metric type; downstream symptoms always appear simultaneously with root causes since distributed systems propagate in sub-seconds.
Q4. You are designing an anomaly detection system for 10,000 IoT sensors. Labelled anomalies exist for only 50 sensors. How do you evaluate model performance across all 10,000?
- A) Evaluate only on the 50 labelled sensors and stop there; performance on the remaining unlabelled sensors cannot be meaningfully measured, and reporting it would misrepresent overall model quality.
- B) Use the 50 labelled sensors purely to tune alert thresholds, then apply those thresholds uniformly across all 10,000 sensors and report the resulting alert rate as the primary evaluation metric.
- C) Train a semi-supervised model treating the 50 labelled sensors as positives and every remaining sensor as a negative example; the resulting F1-score on the 50 labelled sensors alone is sufficient evaluation.
- D) Supervised eval on 50 (PR-AUC/F1), check representativeness; synthetic anomaly injection on unlabelled sensors; monitor alert-rate drift; human-review a sample of alerts for precision.
Try it interactively
ML Systems Lab is a free interview-prep platform for ML engineers — work through the full interactive module, quizzes, and drills.
Open ML Systems Lab →