Skip to main content

timemachines

Temporal online machines: streaming decision layers — anomaly detection first — built on the calibrated surprise streams of skaters.

skating

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"])

That 1e-4 is a false-alarm rate, not a tuned threshold: wald emits a calibrated per-observation p-value, so alarming on p < alpha yields a false-alarm rate of approximately alpha by construction. No other streaming detector family offers that; it is this package's reason to exist.

v2: what happened here

v1 of timemachines was a zoo of forecasting wrappers. It was deprecated in favour of skaters, which does the forecasting job properly: one pass, constant memory, stdlib only, distributional outputs, and — crucially for us — the prediction parade: alongside each forecast, the standardized surprise z of every arriving point under the predictions previously made for it.

v2 is the rebirth one layer up. A skaters forecaster (a body) turns any stream into forecasts plus calibrated surprises; this package's heads turn surprises into decisions with controlled error rates. Bodies are few and stable; heads multiply — that is why they get their own package. (from timemachines import laplace worked in the v1 shim and still works.)

Why a forecaster-first detector

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, the surprise stream is approximately iid N(0,1), which is exactly the homogeneous input every classical detection method assumes and raw data never provides. Two measured consequences (protocols and full tables in 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 laplace-transformed lift
DSPOT (EVT thresholding, KDD 2017) 0.100 0.517 5.2x
RRCF (random cut forest, ICML 2016) 0.250 0.450 1.8x

Other people's forecasters get better too. One-step log-likelihood on 30 FRED series, exact change of variables through the bijection z_t = Phi^-1(F_t(y_t)):

opponent lift (nats/point) wins
ETS +2.04 30/30
AutoARIMA +2.07 30/30
GARCH(1,1) +1.97 30/30
Prophet +2.07 30/30

Fronted opponents converge to the skaters forecaster plus a few hundredths of a nat: the body had already extracted nearly everything they know how to model.

The machines

name job state it adds
wald(k) sequential anomaly detection pvalue (calibrated), d2 (the Wald statistic z' Sigma^-1 z), run (spike vs break)

Named machines are curated recipes — a body, a head, and settings that earned their defaults on benchmarks. The composable parts underneath:

  • mahalanobis(base, k, ...) — the detection head on any parade-wrapped skater: robust streaming location/scatter of the surprise vector (factor model + exact Woodbury inverse), an empirical null (two-moment Satterthwaite, winsorized against masking), Huberised updates with a changepoint escape.
  • zbank(k, sigmas, strides) — a feature bank of bodies across memory and clock scales, concatenated surprises, for multi-scale detection.
  • laplace, parade — re-exported from skaters for convenience.

Roadmap heads, each named for its theorem: page (CUSUM run-length changepoints), pickands (EVT/GPD tails for extreme p-values).

Design rules

  • Bodies live in skaters, heads live here. The API boundary is the parade state contract (state["z"], state["pit"]).
  • Dependency arrows point one way: this package depends on skaters, never the reverse. The core is pure stdlib on top of it; third-party detectors and benchmark tooling sit behind the benchmarks extra.
  • Everything is one-pass, constant-memory, strictly causal: scores at time t use only observations up to t. No whole-series normalisation, ever.

Install

pip install timemachines        # v2: requires skaters

v1 (<2.0) remains on PyPI for pinned users; it is unmaintained.

MIT licensed.

Metadata

Release files for timemachines 2.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for timemachines 2.1.0
File Size Uploaded
timemachines-2.1.0.tar.gz 21.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for timemachines 2.1.0
File Interpreter ABI Platform
timemachines-2.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 37.6 kB

Release files / timemachines-2.1.0.tar.gz

Download URL timemachines-2.1.0.tar.gz
Size 21.2 kB
Tags Source
SHA-256 checksum
How to use checksums
b3b3ead9b0eea89776778353cfa47f4c0e764fb2b3f54694a5077d33b7a0ccd3
BLAKE2b-256 checksum
How to use checksums
49a4a49d9752ca105ad0c5377e05d726b159e2af57348d69acdd15861773c661
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.6

Release files / timemachines-2.1.0-py3-none-any.whl

Download URL timemachines-2.1.0-py3-none-any.whl
Size 16.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c4b26dab9ee1f1a7f65e92615fc627a6f94c31e78febf2b79af92cc859cd307b
BLAKE2b-256 checksum
How to use checksums
7e16e382d502062c3d34df6fcfb5b3a7ae2916efcad65abc2c05055e48281414
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.6

Release history Release notifications | RSS feed

This release

2.1.0 This release

2 release files

2.0.1

2 release files

2.0.0

2 release files

1.0.0

2 release files

0.19.3

2 release files

0.19.2

2 release files

0.18.6

2 release files

0.18.5

2 release files

0.18.1

2 release files

0.15.2

2 release files

0.15.0

2 release files

0.14.7

2 release files

0.14.6

2 release files

0.14.5

2 release files

0.14.3

2 release files

0.12.9

2 release files

0.12.8

2 release files

0.11.7

2 release files

0.11.4

2 release files

0.10.4

2 release files

0.10.3

2 release files

0.10.2

2 release files

0.10.1

2 release files

0.8.10

2 release files

0.8.9

2 release files

0.8.7

2 release files

0.8.6

2 release files

0.8.5

2 release files

0.8.3

2 release files

0.8.2

2 release files

0.8.1

2 release files

0.7.2

2 release files

0.6.8

2 release files

0.6.7

2 release files

0.5.9

2 release files

0.5.8

2 release files

0.5.7

2 release files

0.5.5

2 release files

0.5.4

2 release files

0.5.3

2 release files

0.4.0

2 release files

0.3.6

2 release files

0.3.2

2 release files

0.2.6

2 release files

0.2.0

2 release files

0.1.19

2 release files

0.1.17

2 release files

0.1.16

2 release files

0.1.14

2 release files

0.1.12

2 release files

0.1.11

2 release files

0.1.10

2 release files

0.1.8

2 release files

0.1.7

2 release files

0.1.6

2 release files

0.1.1

2 release files

0.1.0

2 release files

0.0.20

2 release files

0.0.19

2 release files

0.0.18

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page