timemachines
Temporal online machines: streaming anomaly detection with calibrated p-values.
The hard part of anomaly detection is not the detector — it is the
null. A calibrated online forecaster is the best null model there is: under it,
each arriving point's surprise is a standard normal, and detection reduces to the textbook
case. wald runs a skaters
forecaster underneath and emits a p-value per observation — alarm on
p < α and your false-alarm rate is α.
Measured, not asserted: see the calibration panel below.
No threshold tuning, one pass, constant memory, strictly causal.
Live: wald in your browser
Ink dots: the stream. Blue: the model's mean and 95% band
(the null, learned online). Lower strip: -log10 p per tick;
red marks are alarms. This is the actual JavaScript twin of the Python package
running in your tab — not a recording.
Quick start
pip install timemachines # v2: requires skaters
from timemachines import wald
f = wald(k=3)
state = None
for y in stream:
dists, state = f(y, state) # skaters forecasts pass through
if state["pvalue"] is not None and state["pvalue"] < 1e-4:
alarm(y, state["pvalue"], state["run"])
state["run"] separates anomaly types: an isolated spike reads as a point
outlier, a growing run as a structural break.
The transform is the product
skaters' prediction parade converts any stream into standardized surprises zt = Φ−1(Ft(yt)) — a causal bijection (the Rosenblatt transform; see it live). The measured consequence for detection, full protocol in the benchmarks:
Other people's detectors get better in these coordinates
Same detector, same series (UCR anomaly archive, 60 series), only the input changed:
| detector | raw series | transformed | lift |
|---|---|---|---|
| DSPOT — streaming extreme-value thresholding (Siffer et al., KDD 2017) | 0.100 | 0.517 | 5.2× |
| RRCF — Robust Random Cut Forest (Guha et al., ICML 2016; AWS Kinesis) | 0.250 | 0.450 | 1.8× |
The same transform also lifts other people's forecasters (+2 nats/point for ETS, AutoARIMA, GARCH and Prophet, 30/30 series each) — that story belongs to skaters, where it is told.
Calibration, measured
144 anomaly-free real-world prefixes (UCR training regions — clean by construction, so every flag is a false alarm), strictly prequential: nulls and thresholds never see the data they are scored on. Entries are empirical false-alarm rate over nominal α — 1.0 is perfect calibration.
| method | α=10−2 | α=10−3 | α=10−4 |
|---|---|---|---|
wald | 1.69 | 1.86 | 3.20 (median series: 1.00) |
| DSPOT (EVT thresholding, KDD 2017) | 0.98 | 1.95 | 9.34 |
| RRCF, threshold pre-committed on clean data | 1.10 | 1.64 | 5.42 |
At the depth where alarms operate, wald is the best-calibrated streaming
detector measured, and its median series is exactly calibrated. Protocol and full
history in benchmarks/RESULTS.md.
Bodies and heads
A body (a skaters forecaster) turns a stream into forecasts plus
calibrated surprises. A head (this package) turns surprises into
decisions with controlled error rates. Bodies are few and stable; heads multiply.
wald — the Mahalanobis head on the laplace body — is the first named
machine; page (CUSUM run-length) and pickands (EVT tails)
are the roadmap, each named for its theorem.
Package history
v1 of timemachines was a zoo of forecasting wrappers, deprecated in favour of
skaters. v2 is the rebirth one layer
up, and from timemachines import laplace still works. For the century of
ideas behind it, see Heritage.