A strict 4-layer architecture for anomaly detection
Project description
Anomsmith
A strict 4-layer architecture for anomaly detection with hard boundaries between layers.
Architecture
Anomsmith follows a strict 4-layer architecture that enforces clear separation of concerns:
Layer 1: anomsmith.objects - Data and Representations
This layer defines immutable dataclasses for time series data structures. Only numpy and pandas are allowed - no domain libraries (sklearn, matplotlib, etc.).
Components:
SeriesView: Single time series with index and valuesPanelView: Multi-entity series with entity key and time indexScoreView: Anomaly scores aligned to input indexLabelView: Binary flags aligned to input indexWindowSpec: Window specification for time series operationsvalidate: Validators with clear error messages
Layer 2: anomsmith.primitives - Algorithm Interfaces
This layer defines algorithm interfaces and thin utilities. It must not know about tasks or evaluation. Only numpy and pandas are allowed.
Components:
BaseObject: Base class with parameter managementBaseEstimator: Base class with fit and fitted stateBaseScorer: Base class for anomaly scorersBaseDetector: Base class for anomaly detectors- Tag system: Metadata about algorithm capabilities
ThresholdRuleandapply_threshold: Thresholding primitivesrobust_zscore: Robust score scaling using median and MAD
Layer 3: anomsmith.tasks - Task Orchestration
Tasks translate user intent into a sequence of primitive calls and outputs. Tasks must not import matplotlib.
Components:
DetectTask: Task specification dataclassmake_series_view/make_panel_view: Helpers to convert pandas inputsrun_scoring: Task runner for scoringrun_detection: Task runner for detection
Layer 4: anomsmith.workflows - Public API
Workflows provide the public entry points users call. Workflows can import matplotlib only if plots are added.
Components:
score_anomalies: Score anomalies in a time seriesdetect_anomalies: Detect anomalies with thresholdingsweep_thresholds: Evaluate multiple threshold valuesreport_detection: Generate detection report with summary statsanomsmith.workflows.eval: Evaluation subpackage- Metrics: precision, recall, f1, average_run_length
ExpandingWindowSplit: Time series splitter for backtestingbacktest_detector: Run backtests across expanding windows
Installation
pip install anomsmith
Quick Start
import pandas as pd
import numpy as np
from anomsmith import detect_anomalies, RobustZScoreScorer, ThresholdRule
# Create time series
y = pd.Series(np.random.randn(100))
# Initialize scorer
scorer = RobustZScoreScorer()
scorer.fit(y.values)
# Define threshold
threshold_rule = ThresholdRule(method="quantile", value=0.95, quantile=0.95)
# Detect anomalies
result = detect_anomalies(y, scorer, threshold_rule)
print(result.head())
Example
See examples/basic_detect.py for a complete example with synthetic data.
python examples/basic_detect.py
Public API
The public API is exposed in anomsmith.__init__:
score_anomalies: Score anomalies in a time seriesdetect_anomalies: Detect anomalies with thresholdingsweep_thresholds: Evaluate multiple threshold valuesbacktest_detector: Run backtests across expanding windowsBaseScorer: Base class for scorersBaseDetector: Base class for detectorsThresholdRule: Threshold rule dataclass
Included Detectors
RobustZScoreScorer: Robust z-score based anomaly scorer using median and MADChangePointDetector: Change point detector using rolling window statistics
Testing
pytest tests/
Migration Guide
Migrating Existing Detectors
To migrate an existing detector to Anomsmith:
-
Implement Base Interface: Choose
BaseScorerorBaseDetectorbased on whether your detector produces only scores or both scores and labels. -
Follow Layer Rules:
- Layer 1 (objects): Use
SeriesView,ScoreView,LabelViewfor data structures - Layer 2 (primitives): Implement in
anomsmith.primitives.scorersoranomsmith.primitives.detectors - Layer 3 (tasks): Use
run_scoringorrun_detectiontask runners - Layer 4 (workflows): Use public API functions like
detect_anomalies
- Layer 1 (objects): Use
-
Example Migration:
from anomsmith.primitives.base import BaseScorer from anomsmith.objects.views import ScoreView import pandas as pd import numpy as np class MyScorer(BaseScorer): def fit(self, y, X=None): # Fit logic here self._fitted = True return self def score(self, y): # Score logic here index = pd.RangeIndex(len(y)) if not isinstance(y, pd.Series) else y.index scores = np.abs(y) # Example scoring return ScoreView(index=index, scores=scores)
-
Add Tests: Create tests in
tests/following the existing test patterns. -
Update Public API: If the detector should be part of the public API, add it to
anomsmith.__init__.
License
MIT
Contributing
See CONTRIBUTING.md for guidelines.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file anomsmith-0.0.2.tar.gz.
File metadata
- Download URL: anomsmith-0.0.2.tar.gz
- Upload date:
- Size: 29.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e91d24a51697d90202691d33d37bed3433b0b9935aec54e10f41f3a5f9568a1b
|
|
| MD5 |
6606ae4fc430952ced6d028551b43c63
|
|
| BLAKE2b-256 |
ef5d054dc9fab4a271981764f36d8c056d9775861e0bdaee83bef64eef658891
|
Provenance
The following attestation bundles were made for anomsmith-0.0.2.tar.gz:
Publisher:
release.yml on kylejones200/anomsmith
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
anomsmith-0.0.2.tar.gz -
Subject digest:
e91d24a51697d90202691d33d37bed3433b0b9935aec54e10f41f3a5f9568a1b - Sigstore transparency entry: 810688531
- Sigstore integration time:
-
Permalink:
kylejones200/anomsmith@6c63b4c16f0f67878a1c395e316be84c03eca6fa -
Branch / Tag:
refs/tags/v0.0.2 - Owner: https://github.com/kylejones200
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@6c63b4c16f0f67878a1c395e316be84c03eca6fa -
Trigger Event:
push
-
Statement type:
File details
Details for the file anomsmith-0.0.2-py3-none-any.whl.
File metadata
- Download URL: anomsmith-0.0.2-py3-none-any.whl
- Upload date:
- Size: 41.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4cf687b2dc07e20a381dbd1368ccadae3c8cea6af18c1237950276e2577d2e65
|
|
| MD5 |
f36b651a87ddc69166d76d5553c4beff
|
|
| BLAKE2b-256 |
fa7b2ea67738b43619689cfc4e8e07dc2821721e3ae545d0f7091b03699a1260
|
Provenance
The following attestation bundles were made for anomsmith-0.0.2-py3-none-any.whl:
Publisher:
release.yml on kylejones200/anomsmith
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
anomsmith-0.0.2-py3-none-any.whl -
Subject digest:
4cf687b2dc07e20a381dbd1368ccadae3c8cea6af18c1237950276e2577d2e65 - Sigstore transparency entry: 810688557
- Sigstore integration time:
-
Permalink:
kylejones200/anomsmith@6c63b4c16f0f67878a1c395e316be84c03eca6fa -
Branch / Tag:
refs/tags/v0.0.2 - Owner: https://github.com/kylejones200
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@6c63b4c16f0f67878a1c395e316be84c03eca6fa -
Trigger Event:
push
-
Statement type: