Skip to content
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

[DOC] Utils and forecasting api docs #2402

Merged
merged 9 commits into from
Nov 26, 2024
Merged
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
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