Subset-contrast unsupervised model selection for anomaly detection
Project description
subselect
Subset-contrast unsupervised model selection for anomaly detection.
Given a pool of trained anomaly-detection models with no ground-truth labels, pick the best one by measuring the contrast between each model's top-ranked points (predicted anomalies) and the rest of the data.
Why
In anomaly detection, practitioners must choose among many models (Isolation Forest, LOF, kNN, OCSVM, ...) with different hyperparameters. The standard way to evaluate models is supervised, using metrics like ROC-AUC that require labelled anomalies. In practice, labelled anomalies are rarely available; if they were, the problem would already be partly solved.
subselect selects a model from a pool without any labels. A good model
concentrates real anomalies at the top of its score ranking, so its top subset
looks distinct from the rest of the data in feature space; a bad model's top
subset looks like ordinary data. Measuring that contrast with a density or
distance metric gives an unsupervised ranking that correlates with the hidden
supervised ROC-AUC ranking.
Install
pip install subselect
Requires Python 3.10+ with numpy, scipy, pandas, and scikit-learn.
Quickstart
import subselect as ss
# scores: (n_samples, n_models) anomaly score per (sample, model); higher = more anomalous
# X: (n_samples, n_features) original feature matrix
# model_names: length-n_models identifiers aligned with the columns of scores
best = ss.Evaluator().select(scores=scores, X=X, model_names=model_names)
print("Picked:", model_names[best])
Evaluator() selects with a single default metric (Mahalanobis distance). Pass
a list of metrics and ensemble=True to combine several and add their
rank-aggregated ensemble (the strongest configuration in our benchmarks):
ev = ss.Evaluator(metrics=["mahalanobis_distance", "gmm_likelihood"], ensemble=True)
results = ev.evaluate(scores, X, model_names)
print(results.selected_per_metric) # pick per metric, plus 'ensemble'
Shipped metrics
Five contrast metrics across the density and distance families:
| name | family | direction |
|---|---|---|
mahalanobis_distance |
distance, global covariance | higher = better |
knn_avg_distance |
distance, local | higher = better |
lof_score |
local density (LOF) | higher = better |
kde_log_likelihood |
density, non-parametric | lower = better |
gmm_likelihood |
density, parametric | lower = better |
ss.list_metrics() lists them and ss.metric_sets["core"] is all five.
Custom contrast metric
Three ways to add your own:
# 1. Subclass - most flexible
class MyMetric(ss.ContrastMetric):
direction = +1 # higher value -> better model
kind = "per-point"
def fit_reference(self, X_ref): # fit on the complement (the reference)
return self
def score_subset(self, X_sub):
return {"mean": ..., "std": ..., "median": ...}
# 2. Decorator - one function
@ss.contrast_metric(direction=+1, kind="per-point", name="my_metric")
def my_metric(subset_X, reference_X):
return float(...)
# 3. Inline callable - quickest
ss.Evaluator(metrics=[(my_metric_callable, +1)]).select(scores, X, model_names)
Citation
See CITATION.cff. A paper describing the method is forthcoming.
License
MIT. See LICENSE.
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 subselect-0.0.1.tar.gz.
File metadata
- Download URL: subselect-0.0.1.tar.gz
- Upload date:
- Size: 3.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dba3ec4fe73c153c6ab98dd1a575528d81e75b709b9023296c72b3479627f47f
|
|
| MD5 |
910b46448c661d07194c936370b97084
|
|
| BLAKE2b-256 |
2b79094e6ab9ef8faebf5878ad4e61441f8eaa8794838933f24be851d814c3d7
|
File details
Details for the file subselect-0.0.1-py3-none-any.whl.
File metadata
- Download URL: subselect-0.0.1-py3-none-any.whl
- Upload date:
- Size: 4.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7d4ee0207a002361f0df0fa5fe399f2f2428a5e0680100ed274f6d81c8f51e6d
|
|
| MD5 |
ea0cdd065fa3288296e6f7d18870c3d0
|
|
| BLAKE2b-256 |
ae08f248ed44077c089a61e6335c801a017c44618cf486fa31df69149f7e1264
|