API Reference

This page provides detailed API documentation for all Fast-BOCPD classes and functions.

Core Classes

BOCPD

class BOCPD(obs_model, hazard, max_run_length=200)[source]

Bases: object

Bayesian Online Changepoint Detection.

This is a Python wrapper around the C implementation for performance.

Parameters:

max_run_length (int)

__init__(obs_model, hazard, max_run_length=200)[source]

Initialize BOCPD detector.

Parameters:
  • obs_model – Observation model (e.g., GaussianNIG instance)

  • hazard – Hazard function (e.g., ConstantHazard instance)

  • max_run_length (int) – Maximum run length to track

reset()[source]

Reset to prior (as if no data has been seen).

Return type:

None

update(x)[source]

Process one new observation (online mode).

Parameters:

x (float) – New observation

Returns:

Array of P(r_t = r | x_1:t) cp_prob: Probability of changepoint (posterior_r[0])

Return type:

posterior_r

batch_update(data)[source]

Process multiple observations at once (offline mode).

Parameters:

data (ndarray) – Array of observations

Returns:

Array of changepoint probabilities for each time step

Return type:

cp_probs

get_map_run_length()[source]

Get the most likely (MAP) run length at current time.

Returns:

Most likely run length (0 means changepoint just occurred)

Return type:

int

Example

>>> map_r = bocpd.get_map_run_length()
>>> if map_r == 0:
...     print("Changepoint detected!")
>>> else:
...     print(f"Current regime is {map_r} observations old")
get_map_confidence()[source]

Get confidence in the MAP run length estimate.

Returns:

Probability mass at MAP run length (higher = more confident)

Return type:

float

Example

>>> map_r = bocpd.get_map_run_length()
>>> confidence = bocpd.get_map_confidence()
>>> print(f"MAP estimate: r={map_r} (confidence: {confidence:.1%})")
get_posterior()[source]

Get current posterior distribution over run lengths.

Returns:

Array of P(r_t = r | data) for r in [0, max_run_length]

Return type:

posterior_r

close()[source]

Explicitly free C resources (recommended for deterministic cleanup).

__enter__()[source]

Context manager entry.

__exit__(exc_type, exc_val, exc_tb)[source]

Context manager exit.

__del__()[source]

Cleanup C resources (fallback if close() not called).

OnlineChangeDetector

class OnlineChangeDetector(bocpd, min_cp_prob=None, reset_r=2, drop_prev_min=None, cooldown=None, bayes_factor=5.0)[source]

Bases: object

Wrapper for BOCPD optimized for online/streaming detection.

Automatically detects changepoints using: 1. Changepoint probability threshold (P(r_t=0) >= min_cp_prob) 2. MAP run length reset heuristic (sharp drop in estimated segment length)

Features: - Automatic changepoint detection with configurable sensitivity - History tracking - Confidence scoring - Optional metadata attachment - Debouncing to prevent duplicate detections

Example

>>> from fast_bocpd import BOCPD, GaussianNIG, ConstantHazard
>>> from fast_bocpd.utils import OnlineChangeDetector
>>>
>>> bocpd = BOCPD(GaussianNIG(...), ConstantHazard(100))
>>> detector = OnlineChangeDetector(bocpd)
>>>
>>> # Process streaming data
>>> for observation in data_stream:
...     cp = detector.update(observation)
...     if cp:
...         print(f"Changepoint detected: {cp}")
Parameters:
  • min_cp_prob (float | None)

  • reset_r (int)

  • drop_prev_min (int | None)

  • cooldown (int | None)

  • bayes_factor (float)

__init__(bocpd, min_cp_prob=None, reset_r=2, drop_prev_min=None, cooldown=None, bayes_factor=5.0)[source]

Initialize online detector.

Parameters:
  • bocpd – BOCPD instance

  • min_cp_prob (float | None) – Minimum P(r_t=0) to report changepoint If None, computed from hazard using Bayes factor Lower = more sensitive, more false positives Higher = less sensitive, fewer false positives

  • reset_r (int) – MAP run length threshold for “reset” detection (default: 2)

  • drop_prev_min (int | None) – Minimum previous run length for “sharp drop” If None, set to max(10, 0.25*lambda_)

  • cooldown (int | None) – Minimum timesteps between changepoint reports If None, set to max(3, 0.1*lambda_)

  • bayes_factor (float) – Evidence threshold for auto-computing min_cp_prob (default: 5.0) 5=moderate evidence, 10=strong, 3=weak Only used if min_cp_prob is None and hazard is ConstantHazard

update(x, metadata=None)[source]

Process new observation and detect changepoints.

Parameters:
  • x (float) – New observation

  • metadata (Any | None) – Optional metadata to attach (e.g., timestamp, sample ID)

Returns:

Changepoint if detected, None otherwise

Return type:

Changepoint | None

get_current_run_length()[source]

Get time since last detected changepoint.

Returns:

Number of observations since last changepoint detected by this wrapper Returns 0 if no changepoint has been detected yet

Return type:

int

get_current_map_run_length()[source]

Get BOCPD’s current MAP run length estimate.

Returns:

Most likely run length (segment length) according to BOCPD posterior

Return type:

int

get_changepoints()[source]

Get all detected changepoints

Return type:

List[Changepoint]

get_map_history()[source]

Get complete history of MAP run length estimates.

Returns:

List where element i is the MAP run length at time i

Return type:

List[int]

get_segments()[source]

Get segments between changepoints as (start, end) indices.

Note: Segment boundaries are based on detection time (first sample after change).

Returns:

List of (start_idx, end_idx) tuples for each segment

Return type:

List[Tuple[int, int]]

Example

>>> segments = detector.get_segments()
>>> for start, end in segments:
...     print(f"Segment from {start} to {end} (length: {end-start})")
reset()[source]

Reset detector to initial state

__repr__()[source]

String representation for debugging

Return type:

str

Observation Models

GaussianNIG

class GaussianNIG(mu0, kappa0, alpha0, beta0)[source]

Bases: object

1D Gaussian likelihood with Normal-Inverse-Gamma prior.

Prior hyperparameters:

mu0: Prior mean kappa0: Prior precision scaling (must be > 0) alpha0: Prior shape parameter (must be > 0) beta0: Prior scale parameter (must be > 0)

Parameters:

StudentTNG

class StudentTNG(mu0, kappa0, alpha0, beta0, nu=3.0, nu_prior=None)[source]

Bases: object

Student-t observation model with Normal-Gamma prior.

This model is more robust to outliers than Gaussian-NIG. Two modes are supported:

  • Fixed :math:`nu` – pass a scalar nu (standard Student-t).

  • Grid :math:`nu` – pass nu as a list/array and optionally nu_prior to place a discrete prior over different degrees of freedom.

Parameters:
  • mu0 (float) – Prior mean.

  • kappa0 (float) – Prior precision scaling (> 0).

  • alpha0 (float) – Prior shape parameter (> 0).

  • beta0 (float) – Prior rate parameter (> 0).

  • nu (float or array-like, optional) – Degrees of freedom. When nu is an array we infer the best value online via a grid mixture. nu = 1 behaves like Cauchy, nu in [3, 5] is often used for financial data, and \(\nu \to \infty\) approaches Gaussian.

  • nu_prior (array-like, optional) – Prior weights over nu (grid mode). Defaults to uniform weights.

Examples

Fixed ν:

>>> model = StudentTNG(mu0=0, kappa0=1, alpha0=1, beta0=1, nu=3.0)

Grid ν:

>>> model = StudentTNG(mu0=0, kappa0=1, alpha0=1, beta0=1,
...                    nu=[2, 3, 5, 10, 20])

Grid ν with custom prior:

>>> model = StudentTNG(mu0=0, kappa0=1, alpha0=1, beta0=1,
...                    nu=[2, 3, 5], nu_prior=[0.2, 0.5, 0.3])

PoissonGamma

class PoissonGamma(alpha0, beta0, *, strict=True)[source]

Bases: object

Poisson likelihood with Gamma prior on rate parameter (count data).

Conjugate Bayesian model for non-negative integer count data. Predictive distribution is Negative Binomial.

Use this for:
  • Event counts (clicks, transactions, arrivals)

  • Discrete data with λ > 0

  • Overdispersed counts (vs. fixed-rate Poisson)

Prior hyperparameters:
alpha0: Gamma prior shape (must be > 0)

Controls prior belief about rate variability Larger values = more concentrated prior

beta0: Gamma prior rate (must be > 0)

Controls prior belief about expected rate Prior mean rate = alpha0 / beta0

Data requirements:
  • Must be non-negative integers (0, 1, 2, …)

  • In Python, pass as int, float with .0, or integer array

  • Non-integer or negative values will be rejected (strict=True)

Examples

# Event counts with vague prior >>> model = PoissonGamma(alpha0=1.0, beta0=1.0)

# Prior belief: mean rate ≈ 5.0, concentrated >>> model = PoissonGamma(alpha0=50.0, beta0=10.0) # mean = 50/10 = 5

# Disable strict validation (use with caution) >>> model = PoissonGamma(alpha0=1.0, beta0=1.0, strict=False)

Parameters:
validate_data(x)[source]

Validate a single observation (used in update()).

Parameters:

x – Observation (should be non-negative integer)

Raises:

ValueError – If x is invalid and strict=True

validate_batch(data)[source]

Validate and convert batch data to contiguous float64 array.

Parameters:

data (ndarray) – Array-like of observations

Returns:

Validated, contiguous float64 array

Raises:

ValueError – If data is invalid and strict=True

Return type:

ndarray

BernoulliBeta

class BernoulliBeta(alpha0, beta0, *, strict=True)[source]

Bases: object

Bernoulli likelihood with Beta prior on success probability (binary data).

Conjugate Bayesian model for binary outcomes (0/1, success/failure). Predictive distribution is Beta-Bernoulli.

Use this for:
  • Binary classification (yes/no, pass/fail)

  • Conversion rates (click/no-click)

  • A/B testing outcomes

  • Any {0, 1} data

Prior hyperparameters:
alpha0: Beta prior successes (must be > 0)

Controls prior belief about success probability Larger values = more weight on high success rates

beta0: Beta prior failures (must be > 0)

Controls prior belief about failure probability Larger values = more weight on low success rates Prior mean = alpha0 / (alpha0 + beta0)

Data requirements:
  • Must be binary: 0 or 1

  • In Python, pass as int, bool, or float with .0

  • Non-binary values will be rejected (strict=True)

Examples

# Vague prior (uniform over [0,1]) >>> model = BernoulliBeta(alpha0=1.0, beta0=1.0)

# Prior belief: success rate ≈ 0.3, concentrated >>> model = BernoulliBeta(alpha0=30.0, beta0=70.0) # mean = 30/100 = 0.3

# Disable strict validation (use with caution) >>> model = BernoulliBeta(alpha0=1.0, beta0=1.0, strict=False)

Parameters:
validate_data(x)[source]

Validate a single observation (used in update()).

Parameters:

x – Observation (should be 0 or 1)

Raises:

ValueError – If x is invalid and strict=True

validate_batch(data)[source]

Validate and convert batch data to contiguous float64 array.

Parameters:

data (ndarray) – Array-like of observations

Returns:

Validated, contiguous float64 array

Raises:

ValueError – If data is invalid and strict=True

Return type:

ndarray

BinomialBeta

class BinomialBeta(alpha0, beta0, n_trials, *, strict=True)[source]

Bases: object

Binomial likelihood with Beta prior on success probability (fixed-N count data).

Conjugate Bayesian model for binomial outcomes with fixed number of trials. Predictive distribution is Beta-Binomial.

Use this for:
  • Conversion rates per period (k successes in N trials)

  • A/B testing with fixed sample sizes

  • Aggregated binary outcomes

  • Any {0, 1, …, N} count data

Prior hyperparameters:
alpha0: Beta prior successes (must be > 0)

Controls prior belief about success probability Larger values = more weight on high success rates

beta0: Beta prior failures (must be > 0)

Controls prior belief about failure probability Larger values = more weight on low success rates Prior mean = alpha0 / (alpha0 + beta0)

n_trials: Fixed number of trials per observation (must be >= 1)

Each observation is k ∈ {0, 1, …, n_trials}

Data requirements:
  • Must be integers: 0, 1, 2, …, n_trials

  • In Python, pass as int or float with .0

  • Values > n_trials or non-integer will be rejected (strict=True)

Special case:
  • n_trials=1 reduces to Bernoulli-Beta (identical predictive)

Examples

# Conversion rate: 10 trials per period >>> model = BinomialBeta(alpha0=1.0, beta0=1.0, n_trials=10)

# Prior belief: success rate ≈ 0.3, N=20 trials >>> model = BinomialBeta(alpha0=30.0, beta0=70.0, n_trials=20)

# Disable strict validation (use with caution) >>> model = BinomialBeta(alpha0=1.0, beta0=1.0, n_trials=10, strict=False)

Parameters:
validate_data(k)[source]

Validate a single observation (used in update()).

Parameters:

k – Observation (should be integer in 0..n_trials)

Raises:

ValueError – If k is invalid and strict=True

validate_batch(data)[source]

Validate and convert batch data to contiguous float64 array.

Parameters:

data (ndarray) – Array-like of observations

Returns:

Validated, contiguous float64 array

Raises:

ValueError – If data is invalid and strict=True

Return type:

ndarray

GammaGamma

class GammaGamma(alpha0, beta0, shape=1.0, *, strict=True)[source]

Bases: object

Gamma likelihood with Gamma prior on rate parameter (fixed-shape scale data).

Conjugate Bayesian model for positive continuous data with fixed shape. Predictive distribution is Beta-prime-like.

Likelihood: x ~ Gamma(shape=k, rate=λ) [fixed k, unknown λ] Prior: λ ~ Gamma(alpha0, beta0)

Use this for:
  • Positive continuous data with fixed shape

  • Exponential data (special case k=1)

  • Waiting times, survival data, reliability analysis

  • Data with constant coefficient of variation

Prior hyperparameters:
alpha0: Prior shape parameter on rate λ (must be > 0)

Controls prior belief about the rate Larger values = stronger prior belief

beta0: Prior rate parameter on rate λ (must be > 0)

Controls scale of prior on rate Prior mean E[λ] = alpha0 / beta0

shape: Fixed shape parameter k of Gamma likelihood (default 1.0)

Recommended: k >= 1 for well-behaved densities Special case: k=1 gives Exponential distribution

Data requirements:
  • Must be positive: x > 0

  • x=0 is rejected with -∞ log density (k > 1) or special case (k ≈ 1)

  • In strict mode: enforces shape >= 1 (recommended for stability)

Parameterization note:

Uses RATE parameterization (not scale): - Higher rate → smaller values - Mean of Gamma(k, λ) = k/λ - Variance = k/λ²

Special case:
  • shape=1.0: Reduces to Exponential-Gamma (conjugate for exponential data)

Examples

# Exponential waiting times (default) >>> model = GammaGamma(alpha0=1.0, beta0=1.0) # shape=1.0

# Prior: mean rate ≈ 2.0, shape=2.0 >>> model = GammaGamma(alpha0=10.0, beta0=5.0, shape=2.0)

# Disable strict mode (allow shape < 1, use with caution) >>> model = GammaGamma(alpha0=1.0, beta0=1.0, shape=0.5, strict=False)

Parameters:
validate_data(x)[source]

Validate a single observation (used in update()).

Parameters:

x – Observation (should be positive)

Raises:

ValueError – If x is invalid and strict=True

validate_batch(data)[source]

Validate and convert batch data to contiguous float64 array.

Parameters:

data (ndarray) – Array-like of observations

Returns:

Validated, contiguous float64 array

Raises:

ValueError – If data is invalid and strict=True

Return type:

ndarray

Hazard Functions

ConstantHazard

class ConstantHazard(lambda_)[source]

Bases: object

Constant hazard function: \(H = 1 / \lambda\).

At each time step, independent of the current run length r:

P(changepoint) = H P(continuation) = 1 - H

Parameters:
  • lambda (float) – Expected run length (must be > 0)

  • lambda_ (float)

Utility Functions

Helper utilities for changepoint detection in streaming applications.

class Changepoint(index, prev_run_length=0, cp_prob=0.0, map_run_length=0, map_confidence=0.0, observation=0.0, metadata=None)[source]

Bases: object

Record of a detected changepoint

Parameters:
  • index (int)

  • prev_run_length (int)

  • cp_prob (float)

  • map_run_length (int)

  • map_confidence (float)

  • observation (float)

  • metadata (Any | None)

index: int

Time index where changepoint occurred

prev_run_length: int = 0

Estimated length of the segment that just ended (from MAP estimate)

cp_prob: float = 0.0
Type:

Changepoint probability P(r_t=0 | x_1

map_run_length: int = 0

MAP run length estimate at detection time

map_confidence: float = 0.0

Confidence in MAP estimate (max posterior probability)

observation: float = 0.0

Observation value at changepoint

metadata: Any | None = None

Optional user-provided metadata (e.g., timestamp, label)

property confidence: float

Alias for cp_prob (backward compatibility)

class OnlineChangeDetector(bocpd, min_cp_prob=None, reset_r=2, drop_prev_min=None, cooldown=None, bayes_factor=5.0)[source]

Bases: object

Wrapper for BOCPD optimized for online/streaming detection.

Automatically detects changepoints using: 1. Changepoint probability threshold (P(r_t=0) >= min_cp_prob) 2. MAP run length reset heuristic (sharp drop in estimated segment length)

Features: - Automatic changepoint detection with configurable sensitivity - History tracking - Confidence scoring - Optional metadata attachment - Debouncing to prevent duplicate detections

Example

>>> from fast_bocpd import BOCPD, GaussianNIG, ConstantHazard
>>> from fast_bocpd.utils import OnlineChangeDetector
>>>
>>> bocpd = BOCPD(GaussianNIG(...), ConstantHazard(100))
>>> detector = OnlineChangeDetector(bocpd)
>>>
>>> # Process streaming data
>>> for observation in data_stream:
...     cp = detector.update(observation)
...     if cp:
...         print(f"Changepoint detected: {cp}")
Parameters:
  • min_cp_prob (float | None)

  • reset_r (int)

  • drop_prev_min (int | None)

  • cooldown (int | None)

  • bayes_factor (float)

__init__(bocpd, min_cp_prob=None, reset_r=2, drop_prev_min=None, cooldown=None, bayes_factor=5.0)[source]

Initialize online detector.

Parameters:
  • bocpd – BOCPD instance

  • min_cp_prob (float | None) – Minimum P(r_t=0) to report changepoint If None, computed from hazard using Bayes factor Lower = more sensitive, more false positives Higher = less sensitive, fewer false positives

  • reset_r (int) – MAP run length threshold for “reset” detection (default: 2)

  • drop_prev_min (int | None) – Minimum previous run length for “sharp drop” If None, set to max(10, 0.25*lambda_)

  • cooldown (int | None) – Minimum timesteps between changepoint reports If None, set to max(3, 0.1*lambda_)

  • bayes_factor (float) – Evidence threshold for auto-computing min_cp_prob (default: 5.0) 5=moderate evidence, 10=strong, 3=weak Only used if min_cp_prob is None and hazard is ConstantHazard

update(x, metadata=None)[source]

Process new observation and detect changepoints.

Parameters:
  • x (float) – New observation

  • metadata (Any | None) – Optional metadata to attach (e.g., timestamp, sample ID)

Returns:

Changepoint if detected, None otherwise

Return type:

Changepoint | None

get_current_run_length()[source]

Get time since last detected changepoint.

Returns:

Number of observations since last changepoint detected by this wrapper Returns 0 if no changepoint has been detected yet

Return type:

int

get_current_map_run_length()[source]

Get BOCPD’s current MAP run length estimate.

Returns:

Most likely run length (segment length) according to BOCPD posterior

Return type:

int

get_changepoints()[source]

Get all detected changepoints

Return type:

List[Changepoint]

get_map_history()[source]

Get complete history of MAP run length estimates.

Returns:

List where element i is the MAP run length at time i

Return type:

List[int]

get_segments()[source]

Get segments between changepoints as (start, end) indices.

Note: Segment boundaries are based on detection time (first sample after change).

Returns:

List of (start_idx, end_idx) tuples for each segment

Return type:

List[Tuple[int, int]]

Example

>>> segments = detector.get_segments()
>>> for start, end in segments:
...     print(f"Segment from {start} to {end} (length: {end-start})")
reset()[source]

Reset detector to initial state

__repr__()[source]

String representation for debugging

Return type:

str