Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ PyOD 3 is the most comprehensive Python library for anomaly detection. Four pill
=========================== ========================================================================================
Pillar What it means
=========================== ========================================================================================
Multi-Modal 61 detectors across **tabular, time series, graph, text, image, and audio** data, one API
Multi-Modal 62 detectors across **tabular, time series, graph, text, image, and audio** data, one API
Full Lifecycle From raw data to explained anomalies and next-step guidance in a single call
Agentic ``od-expert`` turns natural-language requests into ADEngine workflows; MCP exposes structured tools for other agents
Most Used 46+ million downloads; benchmark-backed routing (ADBench, TSB-AD, BOND, NLP-ADBench)
Expand Down Expand Up @@ -455,6 +455,11 @@ PyOD is organized into two functional groups: **(i) Detection Algorithms**, with
- SUOD: Accelerating Large-scale Unsupervised Heterogeneous OD **(Acceleration)** (`example <https://github.com/yzhao062/pyod/blob/development/examples/suod_example.py>`__)
- 2021
- [#Zhao2021SUOD]_
* - Immune-Inspired
- NSA
- Negative-selection-inspired novelty detection with eleven distinct generation strategies; fit on known normal data (`example <https://github.com/yzhao062/pyod/blob/development/examples/nsa_example.py>`__)
- 1994/2003/2004
- [#Forrest1994Self]_ [#Gonzalez2003Anomaly]_ [#Ji2004Real]_
* - Neural Networks
- AutoEncoder
- Fully connected AutoEncoder (reconstruction error as outlier score) (`example <https://github.com/yzhao062/pyod/blob/development/examples/auto_encoder_example.py>`__)
Expand Down Expand Up @@ -953,3 +958,9 @@ Reference
.. [#Liu2024TSB] Liu, Q., Boniol, P., Palpanas, T. and Paparrizos, J., 2024. TSB-AD: Towards A Reliable Time-Series Anomaly Detection Benchmark. In *Advances in Neural Information Processing Systems (NeurIPS)*.

.. [#Liu2022BOND] Liu, K., Dou, Y., Zhao, Y., Ding, X., Hu, X., Zhang, R., Ding, K., Chen, C., Peng, H., Shu, K., Sun, L., Li, J., Chen, G.H., Jia, Z. and Yu, P.S., 2022. BOND: Benchmarking Unsupervised Outlier Node Detection on Static Attributed Graphs. In *Advances in Neural Information Processing Systems (NeurIPS)*.

.. [#Forrest1994Self] Forrest, S., Perelson, A.S., Allen, L. and Cherukuri, R., 1994. Self-nonself discrimination in a computer. In *Proceedings of 1994 IEEE Computer Society Symposium on Research in Security and Privacy*, pp.202-212. doi:10.1109/RISP.1994.296580.

.. [#Gonzalez2003Anomaly] Gonzalez, F.A. and Dasgupta, D., 2003. Anomaly Detection Using Real-Valued Negative Selection. *Genetic Programming and Evolvable Machines*, 4(4), pp.383-403. doi:10.1023/A:1026195112518.

.. [#Ji2004Real] Ji, Z. and Dasgupta, D., 2004. Real-Valued Negative Selection Algorithm with Variable-Sized Detectors. In *Genetic and Evolutionary Computation - GECCO 2004*, LNCS 3102, pp.287-298. doi:10.1007/978-3-540-24854-5_30.
157 changes: 156 additions & 1 deletion docs/examples/tabular.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Layer 1: Tabular Anomaly Detection
====================================

PyOD has 43 tabular detectors covering probabilistic, linear, proximity, ensemble, and deep learning approaches. All use the same ``fit``/``predict``/``decision_function`` API.
PyOD has 44 tabular detectors covering probabilistic, linear, proximity, ensemble, immune-inspired, and deep learning approaches. All use the same ``fit``/``predict``/``decision_function`` API.

.. code-block:: python

Expand Down Expand Up @@ -41,6 +41,161 @@ All Tabular Examples

----

Negative Selection for Novelty Detection
----------------------------------------

:class:`~pyod.models.nsa.NSA` is one negative-selection-inspired estimator
with distinct generation strategies. Binary matching has three rules, giving
13 configurations across eleven strategies. The public API uses mechanism
names, with no aliases claiming unimplemented published algorithms.

.. list-table:: Implemented generation mechanisms
:header-rows: 1
:widths: 16 44 40

* - Strategy
- Mechanism and source
- Explicit adaptation or limit
* - ``binary``
- Hamming, contiguous-run, or fixed-position chunk matching;
:cite:`forrest1994self`
- Median bit per feature; signed score instead of a binary alarm.
* - ``fixed``
- Random fixed-radius spheres censored against self balls;
:cite:`gonzalez2003anomaly`
- No adaptive population or auxiliary classifier.
* - ``variable``
- Radius equals nearest-self distance minus self radius;
:cite:`ji2004real`
- Bounded draws and center suppression; no coverage certificate.
* - ``coverage``
- Frozen detector sets tested on fresh uniform non-self probes;
:cite:`ji2009vdetector`
- Exact binomial lower bounds with alpha spending replace the original
normal approximation. Budgets can end fitting without certification.
* - ``grid``
- Sparse orthant index, radius-ordered filtering, contained-sphere
removal; :cite:`zhang2013grid`
- Exact nearest search replaces neighbor-only search; bounded depth and
count stopping replace the paper's coverage stopping.
* - ``hierarchical``
- Refined self-cluster balls and restricted candidate boxes;
:cite:`chen2011hierarchical`
- Deterministic Euclidean covers and level budgets; no fractional metric,
built-in PCA, or published coverage termination.
* - ``voronoi``
- Shared vertices of Voronoi cells clipped to the domain;
:cite:`zhu2017quick`
- Two or three features; rectangular domain, finite vertex budget,
optional detector truncation; no distributed Map/Reduce classifier.
* - ``deterministic``
- Regular lattice, censored-column boundary selection, decaying
repulsion; :cite:`barontini2019deterministic`
- Two features; 30 movement steps, safe rejection of failures, optional
thinning. No complete-coverage claim after censoring or thinning.
* - ``suppressed``
- Distance-based self partition, boundary identification, reverse
self detectors that veto negative matches; :cite:`li2010suppression`
- Clean-self interpretation retains outlier selves as reverse detectors;
bounded draws replace published statistical termination.

* - ``dual``
- Adjusted KMeans self envelopes plus negative detectors inside them;
:cite:`zheng2013dual`
- Bounded cluster-count search reports infeasible radius targets;
enclosing radii are expanded by self_radius for self-ball protection.

* - ``annealed``
- Monte Carlo population sizing and overlap-energy minimization by
Metropolis moves; :cite:`gonzalez2003randomized`
- Fixed finite cooling schedule and strict self-ball censoring replace
unspecified initialization and soft-only constraints; no optimality
or asymptotic convergence claim.

These are **NSA-inspired adaptations** with explicit implementation choices,
not complete reproductions or claimed replications of the papers' results.

Fit on **known normal/self observations only**. An anomalous training
observation is also treated as self and can suppress detection around it.
The ``contamination`` parameter sets PyOD's threshold on training scores;
it does not remove contaminated observations or define the geometric
matching boundary. Larger scores mean stronger evidence of non-self.
All real strategies fit a min-max transformation using training data only.
Their bounded domain expands the transformed training bounds by
``sampling_margin``. Geometry strategies require positive domain widths.

For ordinary real strategies, scores are the maximum signed distance inside
any detector sphere. ``suppressed`` additionally takes the minimum with the
signed distance outside the nearest reverse self ball. Thus positive scores
mean a negative match surviving suppression. The ``dual`` strategy takes
the maximum with the signed distance outside all enclosing self balls, so
it also recognizes points far outside the learned envelopes. Binary scores use signed
matching margins. Scores do not depend on other rows in an inference batch.

``coverage`` exposes ``coverage_reached_``, ``coverage_lower_bound_`` and
``coverage_test_count_``. It freezes the population during each complete
``coverage_samples``-probe test and draws fresh probes, rejecting self points.
The one-sided exact binomial bound in round t spends
``(1 - coverage_confidence) / (t * (t + 1))``. The sum of those error budgets
is bounded by ``1 - coverage_confidence``. This controls erroneous coverage
certificates across adaptive rounds under the bounded uniform sampling model.
It does **not** certify anomaly recall, generalization, or coverage outside
the domain. An incomplete round cannot certify coverage. If either budget
prevents certification, fitting warns and ``coverage_reached_`` is false.

``annealed`` first uses at most 256 Monte Carlo probes (at most a quarter
of its candidate budget, with a one-probe minimum) to estimate non-self
volume and an initial detector target capped by ``n_detectors``. It minimizes
Gaussian pair-overlap energy plus a self-affinity penalty of weight one.
Temperature starts at one, proposal neighborhoods start at twice the detector
radius, and both shrink by 0.9 per sweep. Each sweep makes at most twice the
population size in attempts and stops after population-size acceptances.
The best visited population is returned. These finite, documented choices
are adaptations; volume-based sizing is a heuristic without a confidence
certificate. All probes, initialization draws and optimization attempts
share ``max_candidates``. Diagnostics report the target, initial/best energy,
and accepted moves. Strict self-ball censoring applies to every accepted move.

``max_candidates`` counts random draws for sampled strategies, unique cell
vertices for ``voronoi``, and initial lattice sites for ``deterministic``.
The deterministic movement limit is separate: at most 30 steps per selected
boundary site. ``voronoi`` fails explicitly when vertex enumeration exceeds
its budget; it never returns a falsely complete partial tessellation.
``n_detectors`` caps retained negative detectors. Geometry truncation warns.
``generation_diagnostics_`` exposes the mechanism-specific details.

Finite coverage leaves gaps, especially in high dimensions. Real-valued
scores can decrease far outside the domain. Binary quantization discards
magnitudes. Fitting raises if no valid detector can be generated. No
incremental or labeled-feedback API is provided. Voronoi cell enumeration
solves one linear program per unique self sample, so use modest training
sets in two or three dimensions; no speedup over random generation is claimed.

.. code-block:: python

from pyod.models.nsa import NSA

clf = NSA(strategy='coverage', n_detectors=200,
target_coverage=0.9, max_candidates=20000, random_state=42)
clf.fit(X_normal_train)
novelty_scores = clf.decision_function(X_test)
print(clf.coverage_reached_, clf.coverage_lower_bound_)

The runnable `nsa_example.py <https://github.com/yzhao062/pyod/blob/development/examples/nsa_example.py>`__
retains the original raw-feature real-data demonstration and IForest baseline.
`nsa_researched_example.py <https://github.com/yzhao062/pyod/blob/development/examples/nsa_researched_example.py>`__
compares all ten real strategies and IForest on a fixed two-component PCA
representation, fitted only on normal training data. Two components are
chosen before evaluation to include the two-dimensional geometry methods.
This is a separate representation; its scores must not be compared directly
with the raw-feature example to claim an algorithm improvement.
Both examples print held-out AUROC and average precision without test tuning.

The estimator is registered with ``ADEngine`` for explicit construction;
no benchmark rank or automatic routing rule is assigned to it.

----

Example Walkthrough
-------------------

Expand Down
2 changes: 1 addition & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ PyOD 3 is the most comprehensive Python library for anomaly detection. Four pill
=========================== ========================================================================================
Pillar What it means
=========================== ========================================================================================
Multi-Modal 61 detectors across **tabular, time series, graph, text, image, and audio** data, one API
Multi-Modal 62 detectors across **tabular, time series, graph, text, image, and audio** data, one API
Full Lifecycle From raw data to explained anomalies and next-step guidance in a single call
Agentic Ask in plain English, and AI agents run the full detection workflow without OD expertise
Most Used `46+ million downloads <https://pepy.tech/project/pyod>`_; benchmark-backed routing (ADBench, TSB-AD, BOND, NLP-ADBench)
Expand Down
2 changes: 1 addition & 1 deletion docs/install.rst
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ Example output:
.. code-block:: text

PyOD version: 3.1.0
Detectors (ADEngine): 61 total (43 tabular, 7 time-series, 8 graph, 2 text, 2 image, 1 multimodal, 3 audio)
Detectors (ADEngine): 62 total (44 tabular, 7 time-series, 8 graph, 2 text, 2 image, 1 multimodal, 3 audio)
Classic API: OK
ADEngine (Layer 2): OK
MCP extra: OK (run: pyod mcp serve)
Expand Down
12 changes: 11 additions & 1 deletion docs/pyod.models.tabular.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Tabular Detectors
==================

PyOD ships 40+ detectors for tabular data, spanning probabilistic, linear, proximity, ensemble, and deep learning approaches. All inherit from :class:`pyod.models.base.BaseDetector` and use the same ``fit``/``predict``/``decision_function`` API.
PyOD ships 40+ detectors for tabular data, spanning probabilistic, linear, proximity, ensemble, immune-inspired, and deep learning approaches. All inherit from :class:`pyod.models.base.BaseDetector` and use the same ``fit``/``predict``/``decision_function`` API.

See :doc:`examples/tabular` for usage examples and :doc:`api_cc` for the shared API reference.

Expand Down Expand Up @@ -314,6 +314,16 @@ pyod.models.mo\_gaal module
:show-inheritance:


pyod.models.nsa module
----------------------

.. automodule:: pyod.models.nsa
:members:
:exclude-members: get_params, set_params
:undoc-members:
:show-inheritance:


pyod.models.ocsvm module
------------------------

Expand Down
121 changes: 121 additions & 0 deletions docs/zreferences.bib
Original file line number Diff line number Diff line change
Expand Up @@ -682,10 +682,131 @@ @inproceedings{xu2007scan
year={2007}
}

@inproceedings{forrest1994self,
title={Self-nonself discrimination in a computer},
author={Forrest, Stephanie and Perelson, Alan S. and Allen, Lawrence and Cherukuri, Rajesh},
booktitle={Proceedings of 1994 IEEE Computer Society Symposium on Research in Security and Privacy},
pages={202--212},
year={1994},
publisher={IEEE},
doi={10.1109/RISP.1994.296580},
url={https://profsforrest.github.io/homepage/data/publications/1994-self-nonself.pdf}
}

@article{gonzalez2003anomaly,
title={Anomaly Detection Using Real-Valued Negative Selection},
author={Gonz{\'a}lez, Fabio A. and Dasgupta, Dipankar},
journal={Genetic Programming and Evolvable Machines},
volume={4},
number={4},
pages={383--403},
year={2003},
doi={10.1023/A:1026195112518},
url={https://link.springer.com/article/10.1023/A:1026195112518}
}

@inproceedings{ji2004real,
title={Real-Valued Negative Selection Algorithm with Variable-Sized Detectors},
author={Ji, Zhou and Dasgupta, Dipankar},
booktitle={Genetic and Evolutionary Computation -- GECCO 2004},
series={Lecture Notes in Computer Science},
volume={3102},
pages={287--298},
year={2004},
publisher={Springer},
doi={10.1007/978-3-540-24854-5_30},
url={https://digitalcommons.memphis.edu/facpubs/3128/}
}

@inproceedings{liu2022bond,
title={BOND: Benchmarking unsupervised outlier node detection on static attributed graphs},
author={Liu, Kay and Dou, Yingtong and Zhao, Yue and Ding, Xueying and Hu, Xiyang and Zhang, Ruitong and Ding, Kaize and Chen, Canyu and Peng, Hao and Shu, Kai and others},
booktitle={Advances in Neural Information Processing Systems},
volume={35},
year={2022}
}

@article{ji2009vdetector,
title={V-detector: An efficient negative selection algorithm with probably adequate detector coverage},
author={Ji, Zhou and Dasgupta, Dipankar},
journal={Information Sciences},
year={2009},
doi={10.1016/j.ins.2008.12.015},
url={https://doi.org/10.1016/j.ins.2008.12.015},
volume={179},
number={10},
pages={1390--1406}
}

@article{zhang2013grid,
title={A Real-Valued Negative Selection Algorithm Based on Grid for Anomaly Detection},
author={Zhang, Ruirui and Li, Tao and Xiao, Xin},
journal={Abstract and Applied Analysis},
year={2013},
doi={10.1155/2013/268639},
url={https://doi.org/10.1155/2013/268639},
volume={2013},
pages={1--15}
}

@article{chen2011hierarchical,
title={A Negative Selection Algorithm Based on Hierarchical Clustering of Self Set and its Application in Anomaly Detection},
author={Chen, Wen and Liu, Xiao-Jie and Li, Tao and Shi, Yuan-Quan and Zheng, Xu-Fei and Zhao, Hui},
journal={International Journal of Computational Intelligence Systems},
year={2011},
doi={10.2991/ijcis.2011.4.4.1},
url={https://doi.org/10.2991/ijcis.2011.4.4.1},
volume={4},
number={4},
pages={410}
}

@article{zhu2017quick,
title={A Quick Negative Selection Algorithm for One-Class Classification in Big Data Era},
author={Zhu, Fangdong and Chen, Wen and Yang, Hanli and Li, Tao and Yang, Tao and Zhang, Fan},
journal={Mathematical Problems in Engineering},
year={2017},
doi={10.1155/2017/3956415},
url={https://doi.org/10.1155/2017/3956415},
volume={2017},
number={1}
}

@article{barontini2019deterministic,
title={Deterministically generated negative selection algorithm for damage detection in civil engineering systems},
author={Barontini, Alberto and Perera, Ricardo and Masciotta, Maria Giovanna and Amado-Mendes, Paulo and Ramos, Luis and Lourenço, Paulo},
journal={Engineering Structures},
year={2019},
doi={10.1016/j.engstruct.2019.109444},
url={https://doi.org/10.1016/j.engstruct.2019.109444},
volume={197},
pages={109444}
}

@article{li2010suppression,
title={An Outlier Robust Negative Selection Algorithm Inspired by Immune Suppression},
author={Li, Guiyang and Li, Tao and Zeng, Jie and Li, Haibo},
journal={Journal of Computers},
volume={5}, number={9}, pages={1348--1355}, year={2010},
doi={10.4304/jcp.5.9.1348-1355},
url={https://www.jcomputers.us/vol5/jcp0509-07.pdf}
}

@article{zheng2013dual,
title={The Dual Negative Selection Algorithm Based on Pattern Recognition Receptor Theory and Its Application in Two-class Data Classification},
author={Zheng, Xufei and Zhou, Yanhui and Fang, Yonghui},
journal={Journal of Computers},
volume={8}, number={8}, pages={1951--1959}, year={2013},
doi={10.4304/jcp.8.8.1951-1959},
url={https://www.jcomputers.us/vol8/jcp0808-09.pdf}
}

@inproceedings{gonzalez2003randomized,
title={A Randomized Real-Valued Negative Selection Algorithm},
author={Gonzalez, Fabio and Dasgupta, Dipankar and Nino, Luis Fernando},
booktitle={Artificial Immune Systems, ICARIS 2003},
series={Lecture Notes in Computer Science}, volume={2787},
pages={261--272}, year={2003}, publisher={Springer},
doi={10.1007/978-3-540-45192-1_25},
url={https://doi.org/10.1007/978-3-540-45192-1_25}
}
Loading
Loading