Skip to content

ComandanteShche/karaul

Repository files navigation

karaul

Lightweight PELT changepoint detection for TypeScript. No dependencies. Pluggable cost functions.

npm install karaul

Quick start

import { detectChangepoints } from 'karaul';

const dailyCalls = [820, 835, 791, 810, /* ... */ 1240, 1280, 1195]; // call volumes
const changepoints = detectChangepoints(dailyCalls);
// → [59] — volume spike starts at day 59

Pluggable cost functions

karaul ships two cost functions and accepts any custom implementation.

GaussianCost

For real-valued series where noise is approximately normally distributed — temperature readings, latency measurements, stock prices.

import { detectChangepoints, GaussianCost } from 'karaul';

const changepoints = detectChangepoints(series, new GaussianCost());

PoissonCost

For non-negative integer count data — daily call volumes, event counts, incident tallies. The Poisson model is the correct generative assumption for count data and outperforms Gaussian on series where values are bounded at zero.

import { pelt, estimatePenalty, PoissonCost } from 'karaul';

const costFn = new PoissonCost();
const penalty = estimatePenalty(series);
const changepoints = pelt(series, penalty, costFn);

Custom cost functions

Implement the CostFunction interface:

import type { CostFunction, TimeSeries } from 'karaul';

class ExponentialCost implements CostFunction {
    compute(series: TimeSeries, start: number, end: number): number {
        // negative log-likelihood for your distribution
        const n = end - start;
        let sum = 0;
        for (let i = start; i < end; i++) sum += series[i]!;
        const lambda = sum / n; // MLE for rate parameter
        return 2 * n * lambda - 2 * sum * Math.log(lambda + 1e-9);
    }
}

const changepoints = detectChangepoints(series, new ExponentialCost());

API

pelt(series, penalty, costFn)

Core algorithm. Returns an array of changepoint indices.

parameter type description
series number[] Time series values
penalty number BIC penalty per changepoint (use estimatePenalty)
costFn CostFunction Cost function instance

estimatePenalty(series)

Estimates the BIC penalty from the series using robust sigma estimation (MAD of first differences, divisor 0.6745 × √2). Works well for most real-world series. Returns log(n) × log(max(σ², 1)).

detectChangepoints(series, costFn?)

Convenience wrapper: calls estimatePenalty then pelt. Defaults to GaussianCost if costFn is omitted.

Performance

karaul uses in-place active set pruning (splice, backwards iteration) instead of Array.filter(). This eliminates one temporary array allocation per outer loop iteration — n allocations avoided at n=5000. Raw throughput on structured series with real changepoints:

series length time
365 points ~3ms
1000 points ~11ms
5000 points ~124ms

Performance degrades to O(n³) for truly stationary white-noise series where no pruning occurs. This is a property of PELT, not an implementation bug — on real data with structural shifts, the active set stays bounded.

Demo and Examples

See demo/ for a full call analytics pipeline using karaul on synthetic Glados Therapeutics call center data: topic extraction, daily volume aggregation, changepoint detection with PoissonCost, Jira correlation, and LLM causal reasoning.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors