diff --git a/aeon/clustering/feature_based/tests/__init__.py b/aeon/clustering/feature_based/tests/__init__.py new file mode 100644 index 0000000000..d6e8de2247 --- /dev/null +++ b/aeon/clustering/feature_based/tests/__init__.py @@ -0,0 +1 @@ +"""Feature Based learning clustering tests.""" diff --git a/aeon/clustering/feature_based/tests/test_catch22.py b/aeon/clustering/feature_based/tests/test_catch22.py new file mode 100644 index 0000000000..e91ea01982 --- /dev/null +++ b/aeon/clustering/feature_based/tests/test_catch22.py @@ -0,0 +1,88 @@ +"""Tests for Catch22 Clusterer.""" + +import numpy as np +from sklearn import metrics + +from aeon.clustering.feature_based import Catch22Clusterer +from aeon.datasets import load_basic_motions, load_gunpoint + + +def test_catch22_multivariate(): + """Test Catch22 Clusterer with univariate data.""" + X_train, y_train = load_basic_motions(split="train") + X_test, y_test = load_basic_motions(split="test") + num_points = 12 + + X_train = X_train[:num_points] + y_train = y_train[:num_points] + X_test = X_test[:num_points] + y_test = y_test[:num_points] + + catach22 = Catch22Clusterer( + catch24=False, + random_state=1, + ) + train_result = catach22.fit_predict(X_train) + train_score = metrics.rand_score(y_train, train_result) + test_result = catach22.predict(X_test) + test_score = metrics.rand_score(y_test, test_result) + ari_test = metrics.adjusted_rand_score(y_test, test_result) + ari_train = metrics.adjusted_rand_score(y_train, train_result) + predict_proba = catach22.predict_proba(X_test) + + assert len(predict_proba) == 12 + assert ari_test == 0.1927353595255745 + assert ari_train == 0.09810791871058164 + assert len(predict_proba) == 12 + assert np.array_equal( + test_result, + [3, 4, 7, 7, 7, 7, 0, 7, 0, 4, 2, 2], + ) + assert np.array_equal( + train_result, + [7, 3, 0, 5, 6, 4, 7, 7, 4, 7, 1, 2], + ) + assert train_score == 0.4090909090909091 + assert test_score == 0.5 + assert test_result.shape == (12,) + assert train_result.shape == (12,) + + +def test_catch22_univariate(): + """Test Catch22 Clusterer with multivariate data.""" + X_train, y_train = load_gunpoint(split="train") + X_test, y_test = load_gunpoint(split="test") + num_points = 8 + + X_train = X_train[:num_points] + y_train = y_train[:num_points] + X_test = X_test[:num_points] + y_test = y_test[:num_points] + + catach22 = Catch22Clusterer( + catch24=False, + random_state=1, + ) + train_result = catach22.fit_predict(X_train) + train_score = metrics.rand_score(y_train, train_result) + test_result = catach22.predict(X_test) + test_score = metrics.rand_score(y_test, test_result) + ari_test = metrics.adjusted_rand_score(y_test, test_result) + ari_train = metrics.adjusted_rand_score(y_train, train_result) + predict_proba = catach22.predict_proba(X_test) + + assert len(predict_proba) == 8 + assert ari_test == 0.023255813953488372 + assert ari_train == 0.0 + assert np.array_equal( + test_result, + [3, 0, 1, 3, 7, 5, 2, 2], + ) + assert np.array_equal( + train_result, + [5, 0, 3, 7, 4, 6, 2, 1], + ) + assert train_score == 0.42857142857142855 + assert test_score == 0.5714285714285714 + assert test_result.shape == (8,) + assert train_result.shape == (8,) diff --git a/aeon/clustering/feature_based/tests/test_summary.py b/aeon/clustering/feature_based/tests/test_summary.py new file mode 100644 index 0000000000..c2f7a6ec8a --- /dev/null +++ b/aeon/clustering/feature_based/tests/test_summary.py @@ -0,0 +1,48 @@ +"""Tests for Summary Clusterer.""" + +import numpy as np + +from aeon.clustering.feature_based import SummaryClusterer +from aeon.datasets import load_basic_motions, load_gunpoint + + +def test_all_summary_stat_uni(): + """Test Summary Clusterer with all summary stat.""" + X_train, y_train = load_gunpoint(split="train") + X_test, y_test = load_gunpoint(split="test") + num_points = 8 + + X_train = X_train[:num_points] + X_test = X_test[:num_points] + summary_stats_options = ["default", "percentiles", "bowley", "tukey"] + for summary_stat in summary_stats_options: + summary = SummaryClusterer(random_state=1, summary_stats=summary_stat) + train_result = summary.fit_predict(X_train) + test_result = summary.predict(X_test) + predict_proba = summary.predict_proba(X_test) + assert len(predict_proba) == 8 + assert not np.isnan(train_result).any() + assert not np.isnan(test_result).any() + assert test_result.shape == (8,) + assert train_result.shape == (8,) + + +def test_all_summary_stat_multi(): + """Test Summary Clusterer with all summary stat.""" + X_train, y_train = load_basic_motions(split="train") + X_test, y_test = load_basic_motions(split="test") + num_points = 8 + + X_train = X_train[:num_points] + X_test = X_test[:num_points] + summary_stats_options = ["default", "percentiles", "bowley", "tukey"] + for summary_stat in summary_stats_options: + summary = SummaryClusterer(random_state=1, summary_stats=summary_stat) + train_result = summary.fit_predict(X_train) + test_result = summary.predict(X_test) + predict_proba = summary.predict_proba(X_test) + assert len(predict_proba) == 8 + assert not np.isnan(train_result).any() + assert not np.isnan(test_result).any() + assert test_result.shape == (8,) + assert train_result.shape == (8,) diff --git a/aeon/clustering/feature_based/tests/test_tsfresh.py b/aeon/clustering/feature_based/tests/test_tsfresh.py new file mode 100644 index 0000000000..4602b0bf62 --- /dev/null +++ b/aeon/clustering/feature_based/tests/test_tsfresh.py @@ -0,0 +1,64 @@ +"""Tests for TSFresh Clusterer.""" + +import numpy as np +import pytest + +from aeon.clustering.feature_based import TSFreshClusterer +from aeon.datasets import load_basic_motions, load_gunpoint +from aeon.utils.validation._dependencies import _check_soft_dependencies + + +@pytest.mark.skipif( + not _check_soft_dependencies(["tsfresh"], severity="none"), + reason="TSFresh soft dependency unavailable.", +) +def test_all_fc_parameters_uni(): + """Test TSFresh Clusterer with all FC parameters.""" + X_train, y_train = load_gunpoint(split="train") + X_test, y_test = load_gunpoint(split="test") + num_points = 5 + + X_train = X_train[:num_points] + X_test = X_test[:num_points] + fc_parameters = ["minimal", "efficient", "comprehensive"] + for fc in fc_parameters: + tsfresh = TSFreshClusterer( + n_clusters=2, random_state=1, default_fc_parameters=fc + ) + + train_result = tsfresh.fit_predict(X_train) + test_result = tsfresh.predict(X_test) + predict_proba = tsfresh.predict_proba(X_test) + assert len(predict_proba) == 5 + assert not np.isnan(train_result).any() + assert not np.isnan(test_result).any() + assert test_result.shape == (5,) + assert train_result.shape == (5,) + + +@pytest.mark.skipif( + not _check_soft_dependencies(["tsfresh"], severity="none"), + reason="TSFresh soft dependency unavailable.", +) +def test_all_fc_parameters_multi(): + """Test TSFresh Clusterer with all FC parameters.""" + X_train, y_train = load_basic_motions(split="train") + X_test, y_test = load_basic_motions(split="test") + num_points = 5 + + X_train = X_train[:num_points] + X_test = X_test[:num_points] + fc_parameters = ["minimal", "efficient", "comprehensive"] + for fc in fc_parameters: + tsfresh = TSFreshClusterer( + n_clusters=2, random_state=1, default_fc_parameters=fc + ) + + train_result = tsfresh.fit_predict(X_train) + test_result = tsfresh.predict(X_test) + predict_proba = tsfresh.predict_proba(X_test) + assert len(predict_proba) == 5 + assert not np.isnan(train_result).any() + assert not np.isnan(test_result).any() + assert test_result.shape == (5,) + assert train_result.shape == (5,)