Skip to content

Commit

Permalink
[DOC] Utils and forecasting api docs (#2402)
Browse files Browse the repository at this point in the history
* utils and forecasting

* fix and forecasting panel

* fixes

* correct import

* does this fix

* for some reason dev dependencies are needed to build docs

* isolate pytest

* isolate pytest

* add to periodic
  • Loading branch information
MatthewMiddlehurst authored Nov 26, 2024
1 parent 80d1523 commit f4d2daa
Show file tree
Hide file tree
Showing 62 changed files with 581 additions and 176 deletions.
25 changes: 25 additions & 0 deletions .github/workflows/periodic_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,31 @@ jobs:
# Save cache with the current date (ENV set in numba_cache action)
key: numba-run-notebook-examples-${{ runner.os }}-3.10-${{ env.CURRENT_DATE }}

test-core-imports:
runs-on: ubuntu-22.04

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Python 3.10
uses: actions/setup-python@v5
with:
python-version: "3.10"

- name: Install aeon and dependencies
uses: nick-fields/retry@v3
with:
timeout_minutes: 30
max_attempts: 3
command: python -m pip install .

- name: Show dependencies
run: python -m pip list

- name: Run import test
run: python aeon/testing/tests/test_core_imports.py

test-no-soft-deps:
runs-on: ubuntu-22.04

Expand Down
43 changes: 43 additions & 0 deletions .github/workflows/pr_core_dep_import.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: PR module imports

on:
push:
branches:
- main
pull_request:
branches:
- main
paths:
- "aeon/**"
- ".github/workflows/**"
- "pyproject.toml"

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
cancel-in-progress: true

jobs:
test-core-imports:
runs-on: ubuntu-22.04

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Python 3.10
uses: actions/setup-python@v5
with:
python-version: "3.10"

- name: Install aeon and dependencies
uses: nick-fields/retry@v3
with:
timeout_minutes: 30
max_attempts: 3
command: python -m pip install .

- name: Show dependencies
run: python -m pip list

- name: Run import test
run: python aeon/testing/tests/test_core_imports.py
2 changes: 1 addition & 1 deletion .github/workflows/pr_pytest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ jobs:
run: python -m pip list

- name: Run tests
run: python -m pytest -n logical -k 'not TestAll'
run: python -m pytest -n logical

pytest:
runs-on: ${{ matrix.os }}
Expand Down
2 changes: 1 addition & 1 deletion .readthedocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ python:
- docs

build:
os: ubuntu-20.04
os: ubuntu-22.04
tools:
python: "3.10"

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ The following modules are still considered experimental, and the [deprecation po
does not apply:

- `anomaly_detection`
- `forecasting`
- `segmentation`
- `similarity_search`
- `visualisation`
Expand Down
2 changes: 1 addition & 1 deletion aeon/base/tests/test_base_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
UNEQUAL_LENGTH_MULTIVARIATE_CLASSIFICATION,
UNEQUAL_LENGTH_UNIVARIATE_CLASSIFICATION,
)
from aeon.utils import COLLECTIONS_DATA_TYPES
from aeon.utils.data_types import COLLECTIONS_DATA_TYPES
from aeon.utils.validation import get_type


Expand Down
2 changes: 1 addition & 1 deletion aeon/classification/tests/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
EQUAL_LENGTH_UNIVARIATE_CLASSIFICATION,
UNEQUAL_LENGTH_UNIVARIATE_CLASSIFICATION,
)
from aeon.utils import COLLECTIONS_DATA_TYPES
from aeon.utils.data_types import COLLECTIONS_DATA_TYPES

__maintainer__ = []

Expand Down
5 changes: 4 additions & 1 deletion aeon/pipeline/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
"""Pipeline maker utility."""

__all__ = ["make_pipeline", "sklearn_to_aeon"]
__all__ = [
"make_pipeline",
"sklearn_to_aeon",
]

from aeon.pipeline._make_pipeline import make_pipeline
from aeon.pipeline._sklearn_to_aeon import sklearn_to_aeon
8 changes: 4 additions & 4 deletions aeon/regression/compose/tests/test_ensemble.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
make_example_3d_numpy,
make_example_3d_numpy_list,
)
from aeon.testing.mock_estimators import MockHandlesAllInput, MockRegressor
from aeon.testing.mock_estimators import MockRegressor, MockRegressorFullTags

mixed_ensemble = [
DummyRegressor(),
Expand Down Expand Up @@ -114,7 +114,7 @@ def test_unequal_tag_inference():
n_cases=10, min_n_timepoints=8, max_n_timepoints=12, regression_target=True
)

r1 = MockHandlesAllInput()
r1 = MockRegressorFullTags()
r2 = MockRegressor()

assert r1.get_tag("capability:unequal_length")
Expand Down Expand Up @@ -144,7 +144,7 @@ def test_missing_tag_inference():
X, y = make_example_3d_numpy(n_cases=10, n_timepoints=12, regression_target=True)
X[5, 0, 4] = np.nan

r1 = MockHandlesAllInput()
r1 = MockRegressorFullTags()
r2 = MockRegressor()

assert r1.get_tag("capability:missing_values")
Expand Down Expand Up @@ -175,7 +175,7 @@ def test_multivariate_tag_inference():
n_cases=10, n_channels=2, n_timepoints=12, regression_target=True
)

r1 = MockHandlesAllInput()
r1 = MockRegressorFullTags()
r2 = MockRegressor()

assert r1.get_tag("capability:multivariate")
Expand Down
2 changes: 1 addition & 1 deletion aeon/regression/tests/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
EQUAL_LENGTH_UNIVARIATE_REGRESSION,
UNEQUAL_LENGTH_UNIVARIATE_REGRESSION,
)
from aeon.utils import COLLECTIONS_DATA_TYPES
from aeon.utils.data_types import COLLECTIONS_DATA_TYPES


class _TestRegressor(BaseRegressor):
Expand Down
4 changes: 2 additions & 2 deletions aeon/segmentation/tests/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import pytest

from aeon.segmentation.base import BaseSegmenter
from aeon.testing.mock_estimators import MockSegmenter, SupervisedMockSegmenter
from aeon.testing.mock_estimators import MockSegmenter, MockSegmenterRequiresY


def test_fit_predict_correct():
Expand All @@ -25,7 +25,7 @@ def test_fit_predict_correct():
assert res.is_fitted
res = seg.fit_predict(x_correct)
assert isinstance(res, np.ndarray)
seg = SupervisedMockSegmenter()
seg = MockSegmenterRequiresY()
res = seg.fit(x_correct, y=x_correct)
assert res.is_fitted
with pytest.raises(
Expand Down
1 change: 1 addition & 0 deletions aeon/testing/estimator_checking/_estimator_checking.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ class is passed.
{'check_get_params(estimator=MockClassifier())': 'PASSED'}
"""
# check if estimator has soft dependencies installed
_check_soft_dependencies("pytest")
_check_estimator_deps(estimator)

checks = []
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from functools import partial

import numpy as np
import pytest

from aeon.base._base import _clone_estimator
from aeon.base._base_series import VALID_SERIES_INNER_TYPES
Expand Down Expand Up @@ -64,6 +63,8 @@ def check_anomaly_detector_overrides_and_tags(estimator_class):

def check_anomaly_detector_univariate(estimator):
"""Test the anomaly detector on univariate data."""
import pytest

estimator = _clone_estimator(estimator)

if estimator.get_tag(tag_name="capability:univariate"):
Expand All @@ -78,6 +79,8 @@ def check_anomaly_detector_univariate(estimator):

def check_anomaly_detector_multivariate(estimator):
"""Test the anomaly detector on multivariate data."""
import pytest

estimator = _clone_estimator(estimator)

if estimator.get_tag(tag_name="capability:multivariate"):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
_assert_predict_probabilities,
_get_tag,
)
from aeon.utils import COLLECTIONS_DATA_TYPES
from aeon.utils.data_types import COLLECTIONS_DATA_TYPES
from aeon.utils.validation import get_n_cases


Expand Down
3 changes: 2 additions & 1 deletion aeon/testing/estimator_checking/_yield_estimator_checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

import joblib
import numpy as np
import pytest
from numpy.testing import assert_array_almost_equal
from sklearn.exceptions import NotFittedError

Expand Down Expand Up @@ -596,6 +595,8 @@ def check_fit_updates_state_and_cloning(estimator, datatype):

def check_raises_not_fitted_error(estimator, datatype):
"""Check exception raised for non-fit method calls to unfitted estimators."""
import pytest

estimator = _clone_estimator(estimator)

for method in NON_STATE_CHANGING_METHODS:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
)
from aeon.testing.testing_data import FULL_TEST_DATA_DICT
from aeon.testing.utils.estimator_checks import _assert_predict_labels, _get_tag
from aeon.utils import COLLECTIONS_DATA_TYPES
from aeon.utils.data_types import COLLECTIONS_DATA_TYPES


def _yield_regression_checks(estimator_class, estimator_instances, datatypes):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from functools import partial

import numpy as np
import pytest

from aeon.base._base import _clone_estimator
from aeon.base._base_series import VALID_SERIES_INNER_TYPES
Expand Down Expand Up @@ -42,6 +41,8 @@ def check_segmenter_base_functionality(estimator_class):

def check_segmenter_instance(estimator):
"""Test segmenters."""
import pytest

estimator = _clone_estimator(estimator)

def _assert_output(output, dense, length):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@

from functools import partial

import pytest

from aeon.utils.validation._dependencies import (
_check_python_version,
_check_soft_dependencies,
Expand All @@ -23,6 +21,8 @@ def _yield_soft_dependency_checks(estimator_class, estimator_instances, datatype

def check_python_version_softdep(estimator_class):
"""Test that estimators raise error if python version is wrong."""
import pytest

# if dependencies are incompatible skip
softdeps = estimator_class.get_class_tag("python_dependencies", None)
if softdeps is not None and not _check_soft_dependencies(softdeps, severity="none"):
Expand All @@ -46,6 +46,8 @@ def check_python_version_softdep(estimator_class):

def check_python_dependency_softdep(estimator_class):
"""Test that estimators raise error if required soft dependencies are missing."""
import pytest

# if python version is incompatible skip
if not _check_python_version(estimator_class, severity="none"):
return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from aeon.testing.utils.estimator_checks import _run_estimator_method
from aeon.transformations.collection.channel_selection.base import BaseChannelSelector
from aeon.transformations.series import BaseSeriesTransformer
from aeon.utils import COLLECTIONS_DATA_TYPES
from aeon.utils.data_types import COLLECTIONS_DATA_TYPES


def _yield_transformation_checks(estimator_class, estimator_instances, datatypes):
Expand Down
40 changes: 31 additions & 9 deletions aeon/testing/mock_estimators/__init__.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,46 @@
"""Mock estimators for testing and debugging."""

__all__ = [
"make_mock_estimator",
# anomaly detection
"MockAnomalyDetector",
"MockAnomalyDetectorRequiresFit",
"MockAnomalyDetectorRequiresY",
# classification
"MockClassifier",
"MockClassifierPredictProba",
"MockClassifierFullTags",
"MockClassifierParams",
"MockClassifierComposite",
# clustering
"MockCluster",
"MockDeepClusterer",
"MockSegmenter",
"SupervisedMockSegmenter",
"MockHandlesAllInput",
# collection transformation
"MockCollectionTransformer",
# forecasting
"MockForecaster",
# regression
"MockRegressor",
"MockRegressorFullTags",
# segmentation
"MockSegmenter",
"MockSegmenterRequiresY",
# series transformation
"MockSeriesTransformer",
"MockUnivariateSeriesTransformer",
"MockMultivariateSeriesTransformer",
"MockSeriesTransformerNoFit",
"MockUnivariateSeriesTransformer",
"MockCollectionTransformer",
"MockSeriesTransformer",
# similarity search
"MockSimilaritySearch",
]

from aeon.testing.mock_estimators._mock_anomaly_detectors import (
MockAnomalyDetector,
MockAnomalyDetectorRequiresFit,
MockAnomalyDetectorRequiresY,
)
from aeon.testing.mock_estimators._mock_classifiers import (
MockClassifier,
MockClassifierComposite,
MockClassifierFullTags,
MockClassifierParams,
MockClassifierPredictProba,
Expand All @@ -29,17 +49,19 @@
from aeon.testing.mock_estimators._mock_collection_transformers import (
MockCollectionTransformer,
)
from aeon.testing.mock_estimators._mock_forecasters import MockForecaster
from aeon.testing.mock_estimators._mock_regressors import (
MockHandlesAllInput,
MockRegressor,
MockRegressorFullTags,
)
from aeon.testing.mock_estimators._mock_segmenters import (
MockSegmenter,
SupervisedMockSegmenter,
MockSegmenterRequiresY,
)
from aeon.testing.mock_estimators._mock_series_transformers import (
MockMultivariateSeriesTransformer,
MockSeriesTransformer,
MockSeriesTransformerNoFit,
MockUnivariateSeriesTransformer,
)
from aeon.testing.mock_estimators._mock_similarity_search import MockSimilaritySearch
2 changes: 1 addition & 1 deletion aeon/testing/mock_estimators/_mock_anomaly_detectors.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""Mock anomaly detectors for testing."""
"""Mock anomaly detectorsuseful for testing and debugging."""

__maintainer__ = ["MatthewMiddlehurst"]
__all__ = [
Expand Down
Loading

0 comments on commit f4d2daa

Please sign in to comment.