Skip to content

[REF] Refactor Anomaly Detection Module into Submodules by Algorithm Family #2694

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Apr 20, 2025
28 changes: 2 additions & 26 deletions aeon/anomaly_detection/__init__.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,7 @@
"""Time Series Anomaly Detection."""

__all__ = [
"CBLOF",
"COPOD",
"DWT_MLEAD",
"IsolationForest",
"KMeansAD",
"LeftSTAMPi",
"LOF",
"MERLIN",
"OneClassSVM",
"ROCKAD",
"PyODAdapter",
"STOMP",
"STRAY",
"BaseAnomalyDetector",
]

from aeon.anomaly_detection._cblof import CBLOF
from aeon.anomaly_detection._copod import COPOD
from aeon.anomaly_detection._dwt_mlead import DWT_MLEAD
from aeon.anomaly_detection._iforest import IsolationForest
from aeon.anomaly_detection._kmeans import KMeansAD
from aeon.anomaly_detection._left_stampi import LeftSTAMPi
from aeon.anomaly_detection._lof import LOF
from aeon.anomaly_detection._merlin import MERLIN
from aeon.anomaly_detection._one_class_svm import OneClassSVM
from aeon.anomaly_detection._pyodadapter import PyODAdapter
from aeon.anomaly_detection._rockad import ROCKAD
from aeon.anomaly_detection._stomp import STOMP
from aeon.anomaly_detection._stray import STRAY
from aeon.anomaly_detection.base import BaseAnomalyDetector
17 changes: 17 additions & 0 deletions aeon/anomaly_detection/distance_based/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
"""Distance basedTime Series Anomaly Detection."""

__all__ = [
"CBLOF",
"KMeansAD",
"LeftSTAMPi",
"LOF",
"MERLIN",
"STOMP",
]

from aeon.anomaly_detection.distance_based._cblof import CBLOF
from aeon.anomaly_detection.distance_based._kmeans import KMeansAD
from aeon.anomaly_detection.distance_based._left_stampi import LeftSTAMPi
from aeon.anomaly_detection.distance_based._lof import LOF
from aeon.anomaly_detection.distance_based._merlin import MERLIN
from aeon.anomaly_detection.distance_based._stomp import STOMP
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import numpy as np

from aeon.anomaly_detection._pyodadapter import PyODAdapter
from aeon.anomaly_detection.outlier_detection._pyodadapter import PyODAdapter
from aeon.utils.validation._dependencies import _check_soft_dependencies


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class KMeansAD(BaseAnomalyDetector):
Examples
--------
>>> import numpy as np
>>> from aeon.anomaly_detection import KMeansAD
>>> from aeon.anomaly_detection.distance_based import KMeansAD
>>> X = np.array([1, 2, 3, 4, 1, 2, 3, 3, 2, 8, 9, 8, 1, 2, 3, 4], dtype=np.float64)
>>> detector = KMeansAD(n_clusters=3, window_size=4, stride=1, random_state=0)
>>> detector.fit_predict(X)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class LeftSTAMPi(BaseAnomalyDetector):
Internally,this is applying the incremental approach outlined below.

>>> import numpy as np # doctest: +SKIP
>>> from aeon.anomaly_detection import LeftSTAMPi # doctest: +SKIP
>>> from aeon.anomaly_detection.distance_based import LeftSTAMPi # doctest: +SKIP
>>> X = np.random.default_rng(42).random((10)) # doctest: +SKIP
>>> detector = LeftSTAMPi(window_size=3, n_init_train=3) # doctest: +SKIP
>>> detector.fit_predict(X) # doctest: +SKIP
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import numpy as np

from aeon.anomaly_detection._pyodadapter import PyODAdapter
from aeon.anomaly_detection.outlier_detection._pyodadapter import PyODAdapter
from aeon.utils.validation._dependencies import _check_soft_dependencies


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class MERLIN(BaseAnomalyDetector):
Examples
--------
>>> import numpy as np
>>> from aeon.anomaly_detection import MERLIN
>>> from aeon.anomaly_detection.distance_based import MERLIN
>>> X = np.array([1, 2, 3, 4, 1, 2, 3, 4, 2, 3, 4, 5, 1, 2, 3, 4])
>>> detector = MERLIN(min_length=4, max_length=5)
>>> detector.fit_predict(X)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class STOMP(BaseAnomalyDetector):
Examples
--------
>>> import numpy as np
>>> from aeon.anomaly_detection import STOMP # doctest: +SKIP
>>> from aeon.anomaly_detection.distance_based import STOMP # doctest: +SKIP
>>> X = np.random.default_rng(42).random((10, 2), dtype=np.float64)
>>> detector = STOMP(X, window_size=2) # doctest: +SKIP
>>> detector.fit_predict(X, axis=0) # doctest: +SKIP
Expand Down
1 change: 1 addition & 0 deletions aeon/anomaly_detection/distance_based/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Distance based test code."""
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import numpy as np
import pytest

from aeon.anomaly_detection import CBLOF
from aeon.anomaly_detection.distance_based import CBLOF
from aeon.testing.data_generation import make_example_1d_numpy
from aeon.utils.validation._dependencies import _check_soft_dependencies

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import pytest
from sklearn.utils import check_random_state

from aeon.anomaly_detection import KMeansAD
from aeon.anomaly_detection.distance_based import KMeansAD


def test_kmeansad_univariate():
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import numpy as np
import pytest

from aeon.anomaly_detection._left_stampi import LeftSTAMPi
from aeon.anomaly_detection.distance_based._left_stampi import LeftSTAMPi
from aeon.testing.data_generation import make_example_1d_numpy
from aeon.utils.validation._dependencies import _check_soft_dependencies

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import numpy as np
import pytest

from aeon.anomaly_detection import LOF
from aeon.anomaly_detection.distance_based import LOF
from aeon.testing.data_generation import make_example_1d_numpy
from aeon.utils.validation._dependencies import _check_soft_dependencies

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import numpy as np

from aeon.anomaly_detection import MERLIN
from aeon.anomaly_detection.distance_based import MERLIN

TEST_DATA = np.array(
[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import pytest
from sklearn.utils import check_random_state

from aeon.anomaly_detection import STOMP
from aeon.anomaly_detection.distance_based import STOMP
from aeon.utils.validation._dependencies import _check_soft_dependencies


Expand Down
9 changes: 9 additions & 0 deletions aeon/anomaly_detection/distribution_based/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
"""Distribution based Time Series Anomaly Detection."""

__all__ = [
"COPOD",
"DWT_MLEAD",
]

from aeon.anomaly_detection.distribution_based._copod import COPOD
from aeon.anomaly_detection.distribution_based._dwt_mlead import DWT_MLEAD
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import numpy as np

from aeon.anomaly_detection._pyodadapter import PyODAdapter
from aeon.anomaly_detection.outlier_detection._pyodadapter import PyODAdapter
from aeon.utils.validation._dependencies import _check_soft_dependencies


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ class DWT_MLEAD(BaseAnomalyDetector):
Examples
--------
>>> import numpy as np
>>> from aeon.anomaly_detection import DWT_MLEAD
>>> from aeon.anomaly_detection.distribution_based import DWT_MLEAD
>>> X = np.array([1, 2, 3, 4, 1, 2, 3, 3, 2, 8, 9, 8, 1, 2, 3, 4], dtype=np.float64)
>>> detector = DWT_MLEAD(
... start_level=1, quantile_boundary_type='percentile', quantile_epsilon=0.01
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Distribution based test code."""
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import numpy as np
import pytest

from aeon.anomaly_detection import COPOD
from aeon.anomaly_detection.distribution_based import COPOD
from aeon.testing.data_generation import make_example_1d_numpy
from aeon.utils.validation._dependencies import _check_soft_dependencies

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import pytest
from sklearn.utils import check_random_state

from aeon.anomaly_detection import DWT_MLEAD
from aeon.anomaly_detection.distribution_based import DWT_MLEAD


def test_dwt_mlead_output():
Expand Down
11 changes: 11 additions & 0 deletions aeon/anomaly_detection/outlier_detection/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
"""Time Series Outlier Detection."""

__all__ = [
"IsolationForest",
"PyODAdapter",
"STRAY",
]

from aeon.anomaly_detection.outlier_detection._iforest import IsolationForest
from aeon.anomaly_detection.outlier_detection._pyodadapter import PyODAdapter
from aeon.anomaly_detection.outlier_detection._stray import STRAY
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import numpy as np

from aeon.anomaly_detection._pyodadapter import PyODAdapter
from aeon.anomaly_detection.outlier_detection._pyodadapter import PyODAdapter
from aeon.utils.validation._dependencies import _check_soft_dependencies


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class PyODAdapter(BaseAnomalyDetector):
--------
>>> import numpy as np
>>> from pyod.models.lof import LOF # doctest: +SKIP
>>> from aeon.anomaly_detection import PyODAdapter # doctest: +SKIP
>>> from aeon.anomaly_detection.distance_based import PyODAdapter # doctest: +SKIP
>>> X = np.random.default_rng(42).random((10, 2), dtype=np.float64)
>>> detector = PyODAdapter(LOF(), window_size=2) # doctest: +SKIP
>>> detector.fit_predict(X, axis=0) # doctest: +SKIP
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class STRAY(BaseAnomalyDetector):

Examples
--------
>>> from aeon.anomaly_detection import STRAY
>>> from aeon.anomaly_detection.outlier_detection import STRAY
>>> from aeon.datasets import load_airline
>>> import numpy as np
>>> X = load_airline()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Outlier based test code."""
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import pytest
from sklearn.utils import check_random_state

from aeon.anomaly_detection import IsolationForest
from aeon.anomaly_detection.outlier_detection import IsolationForest
from aeon.utils.validation._dependencies import _check_soft_dependencies


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import pytest
from sklearn.utils import check_random_state

from aeon.anomaly_detection import PyODAdapter
from aeon.anomaly_detection.outlier_detection import PyODAdapter
from aeon.utils.validation._dependencies import _check_soft_dependencies


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import numpy as np
from sklearn.preprocessing import MinMaxScaler

from aeon.anomaly_detection import STRAY
from aeon.anomaly_detection.outlier_detection import STRAY


def test_default_1D():
Expand Down
7 changes: 7 additions & 0 deletions aeon/anomaly_detection/sklearn_based/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
"""Sklearn based Anomaly Detection."""

__all__ = [
"OneClassSVM",
]

from aeon.anomaly_detection.sklearn_based._one_class_svm import OneClassSVM
1 change: 1 addition & 0 deletions aeon/anomaly_detection/sklearn_based/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Sklearn based test code."""
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import pytest
from sklearn.utils import check_random_state

from aeon.anomaly_detection import OneClassSVM
from aeon.anomaly_detection.sklearn_based import OneClassSVM


def test_one_class_svm_univariate():
Expand Down
7 changes: 7 additions & 0 deletions aeon/anomaly_detection/whole_series/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
"""Whole Time Series Anomaly Detection."""

__all__ = [
"ROCKAD",
]

from aeon.anomaly_detection.whole_series._rockad import ROCKAD
1 change: 1 addition & 0 deletions aeon/anomaly_detection/whole_series/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Whole series anomaly detection tests."""
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import pytest
from sklearn.utils import check_random_state

from aeon.anomaly_detection import ROCKAD
from aeon.anomaly_detection.whole_series import ROCKAD


def test_rockad_univariate():
Expand Down
58 changes: 49 additions & 9 deletions docs/api_reference/anomaly_detection.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,29 +13,69 @@ Each detector in this module specifies its supported input data format, output d
format, and learning type as an overview table in its documentation. Some detectors
support multiple learning types.

Detectors
---------
Distance-based
--------------

.. currentmodule:: aeon.anomaly_detection
.. currentmodule:: aeon.anomaly_detection.distance_based

.. autosummary::
:toctree: auto_generated/
:template: class.rst

CBLOF
COPOD
DWT_MLEAD
IsolationForest
KMeansAD
LeftSTAMPi
LOF
MERLIN
OneClassSVM
PyODAdapter
ROCKAD
STOMP

Distributin-based
-----------------

.. currentmodule:: aeon.anomaly_detection.distribution_based

.. autosummary::
:toctree: auto_generated/
:template: class.rst

COPOD
DWT_MLEAD

Outlier-Detection
-----------------

.. currentmodule:: aeon.anomaly_detection.outlier_detection

.. autosummary::
:toctree: auto_generated/
:template: class.rst

IsolationForest
PyODAdapter
STRAY

Sklearn-based
-------------

.. currentmodule:: aeon.anomaly_detection.sklearn_based

.. autosummary::
:toctree: auto_generated/
:template: class.rst

OneClassSVM

Whole-Series
------------

.. currentmodule:: aeon.anomaly_detection.whole_series

.. autosummary::
:toctree: auto_generated/
:template: class.rst

ROCKAD

Base
----

Expand Down
Loading