Production-grade unsupervised anomaly detection for drone telemetry
Project description
Agomax
Production-grade unsupervised anomaly detection for drone telemetry
Agomax is a Python package that detects anomalies in drone flight data using unsupervised machine learning. Train once on normal flights, then identify deviations in real-time or batch processing—no labeled anomalies required.
Why Agomax
Drone operations generate high-dimensional telemetry where anomalies are rare and unlabeled. Supervised approaches fail due to insufficient failure examples. Agomax solves this by:
- Learning from normal data only — Train on successful flights
- Using an ensemble approach — Combines 5 complementary unsupervised models
- Adapting to context — Thresholds adjust to flight patterns
- Providing explanations — Shows which models flagged each anomaly
Installation
git clone https://github.com/shaguntembhurne/Agomax.git
cd Agomax
pip install -e .
Requirements: Python 3.8+, NumPy, Pandas, Scikit-learn, SciPy, Joblib
Quick Start
import pandas as pd
from agomax import AgoMaxDetector
# 1. Load normal flight data (no anomalies)
train_df = pd.read_csv("normal_flights.csv")
# 2. Train detector
detector = AgoMaxDetector()
detector.fit(train_df)
# 3. Save for deployment
detector.save("models/drone_detector")
# 4. Load and detect anomalies
detector = AgoMaxDetector.load("models/drone_detector")
test_df = pd.read_csv("new_flight.csv")
result = detector.predict(test_df)
# 5. Access results
print(f"Anomalies detected: {result.labels.sum()}")
print(f"Mean anomaly score: {result.scores.mean():.3f}")
How It Works
Architecture
Agomax uses an ensemble of five unsupervised models to characterize normal behavior:
| Model | Type | Purpose |
|---|---|---|
| KMeans | Clustering | Distance to normal clusters |
| LOF | Density | Local outlier detection |
| One-Class SVM | Margin | Decision boundary around normal data |
| DBSCAN | Clustering | Structural outlier context |
| OPTICS | Clustering | Handles varying densities |
Training Pipeline
Raw Data → Preprocessing → Hyperparameter Tuning → Ensemble Fit → Threshold Learning → Save
- Preprocessing: Numeric coercion, handle missing values, standard scaling
- Tuning: Optimize parameters on normal data to minimize false positives
- Fitting: Train all five models on preprocessed data
- Thresholding: Compute per-model thresholds (default: 99.7th percentile)
- Persistence: Save preprocessor, ensemble, and thresholds to disk
Inference Pipeline
New Data → Transform → Score (per-model) → Threshold → Vote → Anomaly + Confidence
- Transform new data using saved preprocessing pipeline
- Each model computes an anomaly score
- Compare scores against learned thresholds
- Aggregate binary decisions via voting (mean of flags)
- Apply vote threshold (default: 0.4) to classify anomaly
- Compute confidence score for each prediction
Usage Examples
Basic Detection
from agomax import AgoMaxDetector
import pandas as pd
# Train
detector = AgoMaxDetector()
detector.fit(train_df)
detector.save("models/")
# Predict
detector = AgoMaxDetector.load("models/")
result = detector.predict(test_df)
print(result.scores) # Continuous anomaly scores [0-1]
print(result.labels) # Binary labels: 0=normal, 1=anomaly
print(result.events) # Confirmed events after temporal filtering
With Explanations
result = detector.predict(test_df, explain=True)
for i, detail in enumerate(result.details):
if detail['is_anomaly']:
print(f"\nSample {i}:")
print(f" Anomaly Score: {detail['anomaly_score']:.3f}")
print(f" Vote Ratio: {detail['vote_ratio']:.3f}")
print(f" Top Contributors: {detail['top_contributors']}")
print(f" Model Scores: {detail['model_scores']}")
Custom Configuration
from agomax import AgoMaxDetector, DetectorConfig, EnsembleConfig
config = DetectorConfig(
vote_threshold=0.6, # 60% of models must agree
confirmation_steps=5, # Require 5 consecutive anomalies
cooldown_steps=15, # Wait 15 steps after event
ensemble=EnsembleConfig(
kmeans_n_clusters=3,
lof_n_neighbors=30,
ocsvm_nu=0.02,
),
auto_tune=False,
)
detector = AgoMaxDetector(config)
detector.fit(train_df)
Streaming/Real-Time
detector = AgoMaxDetector.load("models/")
while True:
sample = get_telemetry_sample()
sample_df = pd.DataFrame([sample])
result = detector.predict(sample_df)
if result.labels[0]:
print(f"ANOMALY: score={result.scores[0]:.3f}")
if result.events[0]:
print(f"CONFIRMED EVENT - Take action!")
API Reference
AgoMaxDetector
Methods
fit(data, auto_tune=True)— Train on normal datapredict(data, explain=False)— Detect anomalies, returns AnomalyResultsave(directory)— Persist trained detectorload(directory)— Load from disk (classmethod)reset_state()— Reset adaptive thresholds
AnomalyResult
Attributes
scores(ndarray) — Continuous anomaly scores [0-1]labels(ndarray) — Binary labels: 0=normal, 1=anomalyevents(ndarray) — Confirmed events after temporal filteringdetails(list, optional) — Per-sample explanations
Configuration Classes
DetectorConfig
DetectorConfig(
vote_threshold=0.5, # Fraction of models that must agree
confirmation_steps=3, # Consecutive anomalies for event
cooldown_steps=10, # Wait period after event
auto_tune=True, # Auto-tune hyperparameters
)
EnsembleConfig
EnsembleConfig(
kmeans_n_clusters=2,
lof_n_neighbors=20,
ocsvm_nu=0.01,
dbscan_eps=1.2,
optics_min_samples=20,
random_state=42,
)
Best Practices
Training Data
- Use only normal flights—remove known failures
- Include diverse conditions (altitude, speed, weather)
- Minimum 500+ samples recommended
- Ensure data covers expected operational range
Tuning for Production
High false positives:
- Increase
vote_threshold(0.6-0.7) - Increase
confirmation_steps(5-10)
Missing anomalies:
- Decrease
vote_threshold(0.3-0.4) - Ensure training data is sufficiently diverse
Noisy alerts:
- Increase
confirmation_steps - Increase
cooldown_steps
Deployment
- Validate on historical data before production
- Monitor false positive rate and adjust thresholds
- Retrain periodically to capture evolving patterns
- Use explanations to understand alert triggers
- Combine with domain rules—treat as decision support
Limitations
What Agomax Does
- Detects deviations from normal flight patterns
- Handles high-dimensional telemetry without labels
- Adapts to varying flight conditions
What Agomax Doesn't Do
- Classify anomaly types (only flags normal vs. anomalous)
- Predict failures (reactive, not predictive)
- Handle extreme distribution drift without retraining
- Work with tiny datasets (needs ~500+ normal samples)
Assumptions
- Training data is predominantly normal
- Features are numeric or convertible to numeric
- Anomalies manifest in telemetry patterns
- Some false positives are acceptable
Package Structure
agomax/
├── __init__.py # Public API exports
├── detector.py # AgoMaxDetector (main class)
├── config.py # Configuration dataclasses
├── exceptions.py # Custom exceptions
├── utils.py # Data loading utilities
└── core/
├── preprocessing.py # Data preprocessing
├── ensemble.py # Model ensemble
├── threshold.py # Adaptive thresholds
└── tuning.py # Hyperparameter tuning
Contributing
Contributions are welcome. Please:
- Fork the repository
- Create a feature branch (
git checkout -b feature/name) - Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
License
MIT License - see LICENSE file for details.
Citation
@software{agomax2024,
title={Agomax: Production-Grade Anomaly Detection for Drone Telemetry},
author={Tembhurne, Shagun},
year={2024},
url={https://github.com/shaguntembhurne/Agomax}
}
Contact
Shagun Tembhurne
GitHub: @shaguntembhurne
Repository: github.com/shaguntembhurne/Agomax
Built with scikit-learn, pandas, and NumPy.
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 agomax-0.2.3.tar.gz.
File metadata
- Download URL: agomax-0.2.3.tar.gz
- Upload date:
- Size: 25.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.8.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
675daada24f2c19c7b590bacb8c755bc0e22b16c8d941f8c529d610b5a4a7872
|
|
| MD5 |
ad50fcf3d5479cc85c4061d38a383c5a
|
|
| BLAKE2b-256 |
aeadaf366b32050906d27e684c052956a27f21f8654ab3335996896efad9f013
|
File details
Details for the file agomax-0.2.3-py3-none-any.whl.
File metadata
- Download URL: agomax-0.2.3-py3-none-any.whl
- Upload date:
- Size: 25.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.8.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1d0fe538773184e0690b773e041f465148d0e721d3f70e6b5577e9c66ec5437c
|
|
| MD5 |
bf10a72b4b1ee484db6966719c08a0fd
|
|
| BLAKE2b-256 |
daafa84842832f6a57750d00ae7427bc70bad1a4107b100c3e819f140e5c27f3
|