Score events. Learn continuously. Adapt to the stream.
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.
- Extend without framework coupling through typed, structural transformer
and model protocols. The distribution includes
py.typedmetadata.
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 |
| 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, 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
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.
Update and scoring semantics
The evaluation guide covers warm-up separation, label leakage, and useful metrics for imbalanced anomaly streams.
Project
Read the documentation, browse the examples, or report a problem in the issue tracker. Contributions are welcome; start with the contributing guide.
ABERRANT is distributed under the MIT License.
Release files for aberrant 1.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| aberrant-1.1.0.tar.gz | 1.5 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| aberrant-1.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 1.7 MB
Release files / aberrant-1.1.0.tar.gz
| Download URL | aberrant-1.1.0.tar.gz |
|---|---|
| Size | 1.5 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
98380244f0574368f88a2425e0c70b4c87f6226b8265e36a40263fbe01368fd7
|
|
BLAKE2b-256 checksum How to use checksums |
fd135c9f3dfcaa5e2b258fc139e277594f26283ba87fadb3e147aa5e8cd4b615
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.9 {"installer":{"name":"uv","version":"0.9.9"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / aberrant-1.1.0-py3-none-any.whl
| Download URL | aberrant-1.1.0-py3-none-any.whl |
|---|---|
| Size | 181.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0571fb9a48b56663562ab5e6d0c186a570afa40c04cbb38dcfb0aeaf09a9b9eb
|
|
BLAKE2b-256 checksum How to use checksums |
7b90f18f7e8d7cfed923869987bd5b5e6d4a49c224de752a5b29a636dbd0fbc7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.9 {"installer":{"name":"uv","version":"0.9.9"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|