Skip to content

Streaming detector

OnlineChangepointDetector runs the online recursion one observation at a time, for streams of unknown length. See Usage for an example.

Streaming (incremental) online changepoint detection.

online_changepoint_detection needs the whole series up front and returns the [T + 1, T + 1] run-length matrix R. OnlineChangepointDetector runs the same Adams & MacKay (2007) recursion one observation at a time and keeps only the current column of R, so it works on a stream of unknown length (issue #13). With max_run_length set, memory and time per observation are bounded as well.

OnlineChangepointDetector

Incremental Bayesian online changepoint detection (Adams & MacKay 2007).

Feed observations one at a time with update. After each one the detector holds the posterior over the current run length (the number of observations since the last changepoint), which is the column of R that online_changepoint_detection would have produced at that step.

Parameters:

Name Type Description Default
hazard_function callable

Maps a tensor of run lengths to hazard probabilities, e.g. partial(constant_hazard, 250).

required
likelihood_model BaseLikelihood

A fresh online likelihood (StudentT, MultivariateT). It is updated in place and owned by the detector from now on; do not share it with another detector or with online_changepoint_detection.

required
max_run_length int or None

If given, keep run lengths 0 .. max_run_length only: after each update, longer run lengths are dropped and the posterior is renormalized, and the likelihood's parameters for them are pruned. Memory and time per observation are then O(max_run_length) instead of growing with the stream. The result is exact while fewer than max_run_length observations have been seen; after that it is the posterior conditioned on the current segment being at most max_run_length long, which is a good approximation when segments are shorter than that. Default None: exact, and memory grows by one entry per observation.

None
device str, torch.device, or None

Device for the computation; defaults to the likelihood's device.

None

Examples:

>>> from functools import partial
>>> detector = OnlineChangepointDetector(
...     partial(constant_hazard, 250), StudentT(), max_run_length=500
... )
>>> for x in stream:
...     detector.update(x)
...     if detector.changepoint_probability(lag=10) > 0.5:
...         print("segment started at", detector.t - 10)
Notes

The recursion, per observation x_t with run-length posterior r and predictive densities p(x_t | r): r'[k + 1] = r[k] p(x_t | k) (1 - H(k)) and r'[0] = sum_k r[k] p(x_t | k) H(k), then r' is normalized. Adams & MacKay (2007), algorithm 1; the same arithmetic as online_changepoint_detection.

t property

Number of observations processed so far.

run_length_posterior property

P(run length = r | observations so far) for r = 0, 1, ....

A copy, of length t + 1 (or max_run_length + 1 once the bound is reached). Equal to R[:len, t] of online_changepoint_detection on the same data.

map_run_length property

The most probable current run length (argmax of the posterior).

changepoint_probability(lag)

Probability that a new segment started lag observations ago.

That is P(run length = lag): the segment containing the latest observation began at data index t - lag. This is entry t - lag of changepoint_probabilities(R, lag), available as soon as observation t - 1 has been processed. As with that function, lag = 0 is uninformative under a constant hazard; use lag >= 1.

Raises:

Type Description
ValueError

If lag is negative, larger than t, or beyond max_run_length.

update(x)

Process one observation and return the new run-length posterior.

Parameters:

Name Type Description Default
x (float, Tensor or array - like)

A scalar for a univariate likelihood, a [dims] vector for a multivariate one. It is checked before the state changes: a rejected observation leaves the detector as it was.

required

Returns:

Type Description
Tensor

run_length_posterior after x (a copy).