Observed since 20 Oct, 17:20 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
Online Anomaly Detection Models
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.
[!NOTE] ABERRANT 1.x preserves compatibility for its documented public APIs. Private implementation details and exact numeric score sequences are outside that guarantee. See the compatibility policy before upgrading or relying on persisted model state.
| pipelines.PrequentialEvaluator,
explicit warm-up, bounded metric windows, and separate score/update timings.py.typed metadata.ABERRANT requires Python 3.10 or newer and is continuously tested on CPython 3.10, 3.11, and 3.12.
pip install aberrant
| 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]"
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.
| 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.
| 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 |
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.
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.
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.
[!IMPORTANT] For an honest prequential evaluation, call
score_one(event)beforelearn_one(event). Scoring does not call any component'slearn_oneor incorporate the candidate into learned reference state. DuringPipeline.learn_one, each transformer first learns the event and then passes its post-update transform to the next stage. Score scales and warm-up behavior are model-specific, so a single numeric threshold is not portable across detector families.
The evaluation guide covers warm-up separation, label leakage, and useful metrics for imbalanced anomaly streams.
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.
Download counts and popularity will appear here as the collector receives them.
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 1.3.0 | 16 Oct 2026 | 19 |
This describes our collected data; it is not a security assessment.
Observed since 20 Oct, 17:20 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:7ce9aa57708e92584118c0b83663711d81856db596945d2d8030e91e0be76324