Skip to content
OliverHennhoeferPublic

Repository files navigation

Score events. Learn continuously. Adapt to the stream.

PyPI version Supported Python versions CI status Documentation status MIT license

Documentation · Quickstart · Model guide · API reference · Changelog

aberrant is a typed Python library for unsupervised anomaly detection on data that arrives one event at a time. Its models share a compact online interface: score_one(x) evaluates the current event and learn_one(x) updates the model. This lets an application adapt continuously without coordinating an external batch-retraining loop.

Most models consume a dict[str, float], while graph and time-aware models document their required keys explicitly. Detector state, warm-up behavior, memory policy, and score scale remain model-specific rather than being hidden behind a batch-estimator abstraction.

Why aberrant?

  • Use one streaming contract across isolation forests, distance methods, sketches, graph detectors, online statistics, SVMs, time-series methods, and reconstruction models.
  • Choose the right state strategy from sliding windows, bounded sketches, fading summaries, and model-specific incremental updates.
  • Compose online preprocessing with detectors using | pipelines.
  • Discover and configure built-ins through a typed catalog with machine-readable capabilities and an allowlisted declarative builder.
  • Separate detection from policy with drift detectors and static or adaptive score thresholds.
  • Run repeatable experiments with registry-backed benchmark streams and a validated local dataset cache.
  • Compare streaming detectors with a catalog-aware PrequentialEvaluator, explicit warm-up, bounded metric windows, and separate score/update timings.
  • Extend without framework coupling through typed, structural transformer and model protocols. The distribution includes py.typed metadata.

Installation

aberrant requires Python 3.10 or newer and is continuously tested on CPython 3.10, 3.11, and 3.12.

pip install aberrant
Optional extras
Extra Adds
eval scikit-learn metrics for model evaluation
dl the PyTorch-backed Autoencoder
faiss the FAISS similarity-search engine used by models such as KNN
benchmark River and pytest-benchmark
docs the documentation build toolchain
dev linting, typing, testing, and development dependencies
all all optional and development dependencies

For example:

pip install "aberrant[eval,faiss]"

Quick start

The following core-only example learns a scaled isolation forest from a synthetic stream. The first 64 events warm up the pipeline; every later event is scored before it is learned.

import numpy as np

from aberrant.model.iforest import OnlineIsolationForest
from aberrant.transform.preprocessing import StandardScaler

rng = np.random.default_rng(42)
stream = np.vstack(
    [
        rng.normal(size=(400, 2)),
        rng.normal(loc=5.0, size=(20, 2)),
    ]
)

detector = StandardScaler() | OnlineIsolationForest(
    num_trees=25,
    window_size=256,
    seed=42,
)

scores = []
for step, values in enumerate(stream):
    event = {"x": float(values[0]), "y": float(values[1])}

    if step >= 64:
        scores.append((step, detector.score_one(event)))

    detector.learn_one(event)

for step, score in sorted(scores, key=lambda item: item[1], reverse=True)[:5]:
    print(f"event={step}, anomaly_score={score:.3f}")

Higher scores are more anomalous under the common model contract, but their numeric range and calibration differ by detector. Compare or threshold scores only according to the selected model's documented semantics.

Choose a starting point

Goal Start with
General multivariate detection OnlineIsolationForest or another isolation-forest variant
Local-neighborhood or density anomalies LocalOutlierFactor, KNN, SDOStream, or a cell-based detector
Compact projection or frequency sketches StreamingLODA, MStream, or StreamingRSHash
Anomalous edges and graph evolution AnoEdgeL, ISCONNA, MIDAS, or SignedGraphSketchDetector
Discords in a scalar time series RollingMatrixProfile or XLagDAMP
Departures from a known seasonal forecast SeasonalResidualDetector
Changes in relationships between time-series channels MultivariateRollingMatrixProfile
Interpretable rolling statistics Univariate and multivariate moving statistics
Adaptive margin-based detection Online SVM models
Learned reconstruction error OnlineAutoencoderEnsemble or the optional PyTorch Autoencoder
Detecting distribution drift ADWIN, KSWIN, or PageHinkley
Turning a score into an alert signal QuantileThreshold or ThresholdModel

See the model guide for inputs, score interpretation, warm-up behavior, and memory characteristics.

Included public model families
Family Implementations
Isolation forest ASDIsolationForest, HalfSpaceTrees, MondrianIsolationForest, OnlineIsolationForest, RandomCutForest, StreamRandomHistogramForest, XStream
Distance CellNeighborhoodDetector, KNN, LocalOutlierFactor, SDOStream, StationaryRegionNeighborDetector
Sketch MStream, StreamingLODA, StreamingRSHash
Graph AnoEdgeL, ISCONNA, MIDAS, SignedGraphSketchDetector
Time series MultivariateRollingMatrixProfile, RollingMatrixProfile, SeasonalResidualDetector, XLagDAMP
SVM GraphGatedOneClassSVM, IncrementalOneClassSVMAdaptiveKernel
Statistical MovingAverage, MovingAverageAbsoluteDeviation, MovingGeometricAverage, MovingHarmonicAverage, MovingInterquartileRange, MovingKurtosis, MovingMedian, MovingQuantile, MovingSkewness, MovingVariance, MovingCorrelationCoefficient, MovingCovariance, MovingMahalanobisDistance
Reconstruction OnlineAutoencoderEnsemble, optional Autoencoder
Score policy QuantileThreshold, ThresholdModel
Baselines NullModel, RandomModel
Drift detection ADWIN, KSWIN, PageHinkley

Pipelines and custom components

Transformers compose left to right, with at most one terminal model:

from aberrant.model.iforest import OnlineIsolationForest
from aberrant.transform import IncrementalPCA, StandardScaler

detector = (
    StandardScaler()
    | IncrementalPCA(n_components=3, n0=100)
    | OnlineIsolationForest(window_size=512, seed=42)
)

Any custom object satisfying TransformerProtocol or ModelProtocol can join a pipeline; subclassing an aberrant base class is optional. Read the pipeline guide for lifecycle and composition rules.

Application integration

RollingRobustScaler adds exact median/IQR scaling over bounded recent feature windows. Its freeze() and unfreeze() controls make calibration updates explicit; see the transformer guide for readiness, zero-IQR behavior, and downstream coordinate considerations.

The built-in catalog makes model facts and construction available to services, configuration UIs, and deployment tooling without duplicating import paths or warm-up formulas:

from aberrant.catalog import DetectorConfig, get_model_spec

spec = get_model_spec("online_isolation_forest")
print(spec.parameter_schema())

config = DetectorConfig.from_mapping(
    {
        "transformers": [
            {
                "id": "feature_schema_guard",
                "params": {"features": ["temperature", "pressure"]},
            },
            {"id": "standard_scaler"},
        ],
        "model": {
            "id": "online_isolation_forest",
            "params": {"window_size": 512, "seed": 42},
        },
    }
)
detector = config.build()

See the application integration guide for the catalog manifest, capability fields, KNN/FAISS configuration, and the boundary between package metadata and application policy.

Streaming datasets

The dataset API downloads, validates, and caches registered benchmark data, then exposes it as feature dictionaries and evaluation labels:

from itertools import islice

from aberrant.model.iforest import OnlineIsolationForest
from aberrant.stream.dataset import Dataset, load

dataset = load(Dataset.SHUTTLE)
detector = OnlineIsolationForest(num_trees=25, window_size=512, seed=42)

for event, label in islice(dataset.stream(), 100):
    score = detector.score_one(event)
    detector.learn_one(event)
    print(f"label={label!r}, anomaly_score={score:.3f}")

Labels are provided for evaluation; unsupervised detectors learn only from the event mapping. Cache location and download behavior are configurable through the streaming guide.