Documentation · Quickstart · Model guide · Evaluation · API reference · Changelog
Running it in production? The integration guide shows how to build detectors from configurations.
# pip install "aberrant[eval]"
from itertools import islice
from aberrant.drift import ADWIN
from aberrant.evaluate import PrequentialEvaluator
from aberrant.model import QuantileThreshold
from aberrant.model.distance import SDOStream
from aberrant.stream.dataset import Dataset, load
from aberrant.transform import IncrementalPCA, StandardScaler
stream = load(Dataset.SHUTTLE).stream()
preprocess = StandardScaler() | IncrementalPCA(n_components=5, n0=100)
for event, _ in islice(stream, 512):
preprocess.learn_one(event)
detector = SDOStream(k=128, seed=42)
evaluator = PrequentialEvaluator(
detector,
warmup=256,
metrics=True,
metric_window_size=None, # Retain all labeled scores for full-stream metrics.
)
threshold = QuantileThreshold(quantile=0.99, window_size=256)
drift = ADWIN(max_window_size=2048)
projected_stream = ((preprocess.transform_one(event), label) for event, label in stream)
alerts = 0
for record in evaluator.iter_evaluate(projected_stream):
score = record.score
if score is None: # The detector is still warming up.
continue
score_event = {"score": score}
if threshold.score_one(score_event) == 1.0:
alerts += 1
threshold.learn_one(score_event)
drift.update(score)
result = evaluator.result()
print(f"Average precision = {result.average_precision:.3f}")
print(f"{alerts} alerts, {drift.n_detections} score drift signals")- Broad toolbox. Forest, density, sketch, graph, matrix-profile, SVM and autoencoder detectors.
- Score to alert. Drift detectors and adaptive thresholds turn scores into decisions.
- Built for services.
|pipelines, bounded state, detectors built from plain configuration. - Measured on the stream. Prequential evaluation, benchmark streams, separate timings.
- Typed and extensible. Ships
py.typedand any protocol-conforming object joins a pipeline.
| aberrant | river | PySAD | |
|---|---|---|---|
| Isolation forests and half-space trees | ✓ | ✓ | ✓ |
| Projection sketches (LODA, RS-Hash) | ✓ | ✓ | ✓ |
| Graph-edge streams (MIDAS, AnoEdge, ISCONNA) | ✓ | ||
| Time-series discords (matrix profile, DAMP) | ✓ | ||
| Drift detectors (ADWIN, KSWIN, Page-Hinkley) | ✓ | ✓ | |
| Score thresholds or calibration | ✓ | ✓ | ✓ |
| Detectors built from declarative configuration | ✓ | ||
| General online ML (classification, regression) | ✓ |
Many anomalies have no outlying value at all. In this ECG from the UCR Time
Series Anomaly Archive, one malformed heartbeat sits among roughly 180 normal
ones, under sensor noise and baseline wander, and every one of its values lies
inside the normal range. XLagDAMP, a matrix-profile discord detector, scores
the stream in a single pass from the first sample, with no training split and
bounded memory, and its highest score lands on that beat. Because the beat
differs in shape rather than in value, a detector that scores single values has
no outlier to find.
Series 013_UCR_Anomaly_DISTORTEDECG3 (Wu and Keogh, 2021), with XLagDAMP(subsequence_length=167). Reproduce with docs/scripts/discord_figure.py.
aberrant requires Python 3.11 or newer and is continuously tested on CPython
3.11 to 3.14 on Linux and Windows.
pip install aberrantOptional 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]"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, OnlineECOD, OnlineCOPOD |
| Reconstruction | OnlineAutoencoderEnsemble, optional Autoencoder |
| Score policy | QuantileThreshold, ThresholdModel |
| Baselines | NullModel, RandomModel |
| Drift detection | ADWIN, KSWIN, PageHinkley |
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() # PCA needs features on comparable scales
| IncrementalPCA(n_components=3, n0=100)
| OnlineIsolationForest(window_size=512, seed=42)
)Read the pipeline guide for lifecycle and composition rules.