From 123ff9eae794a17b7ba0f958648b5006e6bb0918 Mon Sep 17 00:00:00 2001 From: Lars Reimann Date: Sun, 26 Mar 2023 16:56:21 +0200 Subject: [PATCH] test: restructure `ml` tests (#81) ### Summary of Changes * Reduce code duplication by using fixtures * Group tests of a method into a class, so we can have one test file per source file --------- Co-authored-by: lars-reimann --- .github/linters/.pylintrc | 1 + .../ml/classification/_ada_boost/__init__.py | 0 .../ml/classification/_ada_boost/test_fit.py | 21 ---- .../classification/_ada_boost/test_predict.py | 33 ------- .../ml/classification/_classifier/__init__.py | 0 .../_classifier/test_accuracy.py | 20 ---- .../classification/_decision_tree/__init__.py | 0 .../classification/_decision_tree/test_fit.py | 21 ---- .../_decision_tree/test_predict.py | 35 ------- .../_gradient_boosting/__init__.py | 0 .../_gradient_boosting/test_fit.py | 25 ----- .../_gradient_boosting/test_predict.py | 41 -------- .../_k_nearest_neighbors/__init__.py | 0 .../_k_nearest_neighbors/test_fit.py | 23 ----- .../_k_nearest_neighbors/test_predict.py | 35 ------- .../_logistic_regression/__init__.py | 0 .../_logistic_regression/test_fit.py | 23 ----- .../_logistic_regression/test_predict.py | 35 ------- .../classification/_random_forest/__init__.py | 0 .../classification/_random_forest/test_fit.py | 21 ---- .../_random_forest/test_predict.py | 35 ------- .../ml/classification/test_ada_boost.py | 58 +++++++++++ ...dummy_classifier.py => test_classifier.py} | 19 +++- .../ml/classification/test_decision_tree.py | 58 +++++++++++ .../classification/test_gradient_boosting.py | 62 ++++++++++++ .../test_k_nearest_neighbors.py | 60 ++++++++++++ .../test_logistic_regression.py | 60 ++++++++++++ .../ml/classification/test_random_forest.py | 58 +++++++++++ .../ml/regression/_ada_boost/__init__.py | 0 .../ml/regression/_ada_boost/test_fit.py | 21 ---- .../ml/regression/_ada_boost/test_predict.py | 33 ------- .../ml/regression/_decision_tree/__init__.py | 0 .../ml/regression/_decision_tree/test_fit.py | 21 ---- .../regression/_decision_tree/test_predict.py | 35 ------- .../ml/regression/_elastic_net/__init__.py | 0 .../ml/regression/_elastic_net/test_fit.py | 23 ----- .../regression/_elastic_net/test_predict.py | 35 ------- .../_gradient_boosting_regression/__init__.py | 0 .../_gradient_boosting_regression/test_fit.py | 25 ----- .../test_predict.py | 41 -------- .../_k_nearest_neighbors/__init__.py | 0 .../_k_nearest_neighbors/test_fit.py | 23 ----- .../_k_nearest_neighbors/test_predict.py | 35 ------- .../regression/_lasso_regression/__init__.py | 0 .../regression/_lasso_regression/test_fit.py | 21 ---- .../_lasso_regression/test_predict.py | 35 ------- .../regression/_linear_regression/__init__.py | 0 .../regression/_linear_regression/test_fit.py | 21 ---- .../_linear_regression/test_predict.py | 35 ------- .../ml/regression/_random_forest/__init__.py | 0 .../ml/regression/_random_forest/test_fit.py | 21 ---- .../regression/_random_forest/test_predict.py | 35 ------- .../ml/regression/_regressor/__init__.py | 0 .../regression/_regressor/_dummy_regressor.py | 26 ----- .../test_check_metrics_preconditions.py | 30 ------ .../_regressor/test_mean_absolute_error.py | 26 ----- .../_regressor/test_mean_squared_error.py | 20 ---- .../regression/_ridge_regression/__init__.py | 0 .../regression/_ridge_regression/test_fit.py | 21 ---- .../_ridge_regression/test_predict.py | 35 ------- .../safeds/ml/regression/metrics/__init__.py | 0 tests/safeds/ml/regression/test_ada_boost.py | 58 +++++++++++ .../ml/regression/test_decision_tree.py | 58 +++++++++++ .../safeds/ml/regression/test_elastic_net.py | 60 ++++++++++++ .../ml/regression/test_gradient_boosting.py | 62 ++++++++++++ .../ml/regression/test_k_nearest_neighbors.py | 60 ++++++++++++ .../ml/regression/test_lasso_regression.py | 58 +++++++++++ .../ml/regression/test_linear_regression.py | 58 +++++++++++ .../ml/regression/test_random_forest.py | 58 +++++++++++ tests/safeds/ml/regression/test_regressor.py | 98 +++++++++++++++++++ .../ml/regression/test_ridge_regression.py | 58 +++++++++++ 71 files changed, 1003 insertions(+), 987 deletions(-) delete mode 100644 tests/safeds/ml/classification/_ada_boost/__init__.py delete mode 100644 tests/safeds/ml/classification/_ada_boost/test_fit.py delete mode 100644 tests/safeds/ml/classification/_ada_boost/test_predict.py delete mode 100644 tests/safeds/ml/classification/_classifier/__init__.py delete mode 100644 tests/safeds/ml/classification/_classifier/test_accuracy.py delete mode 100644 tests/safeds/ml/classification/_decision_tree/__init__.py delete mode 100644 tests/safeds/ml/classification/_decision_tree/test_fit.py delete mode 100644 tests/safeds/ml/classification/_decision_tree/test_predict.py delete mode 100644 tests/safeds/ml/classification/_gradient_boosting/__init__.py delete mode 100644 tests/safeds/ml/classification/_gradient_boosting/test_fit.py delete mode 100644 tests/safeds/ml/classification/_gradient_boosting/test_predict.py delete mode 100644 tests/safeds/ml/classification/_k_nearest_neighbors/__init__.py delete mode 100644 tests/safeds/ml/classification/_k_nearest_neighbors/test_fit.py delete mode 100644 tests/safeds/ml/classification/_k_nearest_neighbors/test_predict.py delete mode 100644 tests/safeds/ml/classification/_logistic_regression/__init__.py delete mode 100644 tests/safeds/ml/classification/_logistic_regression/test_fit.py delete mode 100644 tests/safeds/ml/classification/_logistic_regression/test_predict.py delete mode 100644 tests/safeds/ml/classification/_random_forest/__init__.py delete mode 100644 tests/safeds/ml/classification/_random_forest/test_fit.py delete mode 100644 tests/safeds/ml/classification/_random_forest/test_predict.py create mode 100644 tests/safeds/ml/classification/test_ada_boost.py rename tests/safeds/ml/classification/{_classifier/_dummy_classifier.py => test_classifier.py} (50%) create mode 100644 tests/safeds/ml/classification/test_decision_tree.py create mode 100644 tests/safeds/ml/classification/test_gradient_boosting.py create mode 100644 tests/safeds/ml/classification/test_k_nearest_neighbors.py create mode 100644 tests/safeds/ml/classification/test_logistic_regression.py create mode 100644 tests/safeds/ml/classification/test_random_forest.py delete mode 100644 tests/safeds/ml/regression/_ada_boost/__init__.py delete mode 100644 tests/safeds/ml/regression/_ada_boost/test_fit.py delete mode 100644 tests/safeds/ml/regression/_ada_boost/test_predict.py delete mode 100644 tests/safeds/ml/regression/_decision_tree/__init__.py delete mode 100644 tests/safeds/ml/regression/_decision_tree/test_fit.py delete mode 100644 tests/safeds/ml/regression/_decision_tree/test_predict.py delete mode 100644 tests/safeds/ml/regression/_elastic_net/__init__.py delete mode 100644 tests/safeds/ml/regression/_elastic_net/test_fit.py delete mode 100644 tests/safeds/ml/regression/_elastic_net/test_predict.py delete mode 100644 tests/safeds/ml/regression/_gradient_boosting_regression/__init__.py delete mode 100644 tests/safeds/ml/regression/_gradient_boosting_regression/test_fit.py delete mode 100644 tests/safeds/ml/regression/_gradient_boosting_regression/test_predict.py delete mode 100644 tests/safeds/ml/regression/_k_nearest_neighbors/__init__.py delete mode 100644 tests/safeds/ml/regression/_k_nearest_neighbors/test_fit.py delete mode 100644 tests/safeds/ml/regression/_k_nearest_neighbors/test_predict.py delete mode 100644 tests/safeds/ml/regression/_lasso_regression/__init__.py delete mode 100644 tests/safeds/ml/regression/_lasso_regression/test_fit.py delete mode 100644 tests/safeds/ml/regression/_lasso_regression/test_predict.py delete mode 100644 tests/safeds/ml/regression/_linear_regression/__init__.py delete mode 100644 tests/safeds/ml/regression/_linear_regression/test_fit.py delete mode 100644 tests/safeds/ml/regression/_linear_regression/test_predict.py delete mode 100644 tests/safeds/ml/regression/_random_forest/__init__.py delete mode 100644 tests/safeds/ml/regression/_random_forest/test_fit.py delete mode 100644 tests/safeds/ml/regression/_random_forest/test_predict.py delete mode 100644 tests/safeds/ml/regression/_regressor/__init__.py delete mode 100644 tests/safeds/ml/regression/_regressor/_dummy_regressor.py delete mode 100644 tests/safeds/ml/regression/_regressor/test_check_metrics_preconditions.py delete mode 100644 tests/safeds/ml/regression/_regressor/test_mean_absolute_error.py delete mode 100644 tests/safeds/ml/regression/_regressor/test_mean_squared_error.py delete mode 100644 tests/safeds/ml/regression/_ridge_regression/__init__.py delete mode 100644 tests/safeds/ml/regression/_ridge_regression/test_fit.py delete mode 100644 tests/safeds/ml/regression/_ridge_regression/test_predict.py delete mode 100644 tests/safeds/ml/regression/metrics/__init__.py create mode 100644 tests/safeds/ml/regression/test_ada_boost.py create mode 100644 tests/safeds/ml/regression/test_decision_tree.py create mode 100644 tests/safeds/ml/regression/test_elastic_net.py create mode 100644 tests/safeds/ml/regression/test_gradient_boosting.py create mode 100644 tests/safeds/ml/regression/test_k_nearest_neighbors.py create mode 100644 tests/safeds/ml/regression/test_lasso_regression.py create mode 100644 tests/safeds/ml/regression/test_linear_regression.py create mode 100644 tests/safeds/ml/regression/test_random_forest.py create mode 100644 tests/safeds/ml/regression/test_regressor.py create mode 100644 tests/safeds/ml/regression/test_ridge_regression.py diff --git a/.github/linters/.pylintrc b/.github/linters/.pylintrc index 368ee93b7..64f4955dd 100644 --- a/.github/linters/.pylintrc +++ b/.github/linters/.pylintrc @@ -32,6 +32,7 @@ disable= wrong-import-order, # False positives import-error, + redefined-outer-name, # Unwanted design, duplicate-code, diff --git a/tests/safeds/ml/classification/_ada_boost/__init__.py b/tests/safeds/ml/classification/_ada_boost/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/safeds/ml/classification/_ada_boost/test_fit.py b/tests/safeds/ml/classification/_ada_boost/test_fit.py deleted file mode 100644 index d62e69c88..000000000 --- a/tests/safeds/ml/classification/_ada_boost/test_fit.py +++ /dev/null @@ -1,21 +0,0 @@ -import pytest -from safeds.data.tabular.containers import Table, TaggedTable -from safeds.exceptions import LearningError -from safeds.ml.classification import AdaBoost -from tests.fixtures import resolve_resource_path - - -def test_ada_boost_fit() -> None: - table = Table.from_csv(resolve_resource_path("test_ada_boost.csv")) - tagged_table = TaggedTable(table, "T") - ada_boost = AdaBoost() - ada_boost.fit(tagged_table) - assert True # This asserts that the fit method succeeds - - -def test_ada_boost_fit_invalid() -> None: - table = Table.from_csv(resolve_resource_path("test_ada_boost_invalid.csv")) - tagged_table = TaggedTable(table, "T") - ada_boost = AdaBoost() - with pytest.raises(LearningError): - ada_boost.fit(tagged_table) diff --git a/tests/safeds/ml/classification/_ada_boost/test_predict.py b/tests/safeds/ml/classification/_ada_boost/test_predict.py deleted file mode 100644 index bbaa52b8f..000000000 --- a/tests/safeds/ml/classification/_ada_boost/test_predict.py +++ /dev/null @@ -1,33 +0,0 @@ -import pytest -from safeds.data.tabular.containers import Table, TaggedTable -from safeds.exceptions import PredictionError -from safeds.ml.classification import AdaBoost -from tests.fixtures import resolve_resource_path - - -def test_ada_boost_predict() -> None: - table = Table.from_csv(resolve_resource_path("test_ada_boost.csv")) - tagged_table = TaggedTable(table, "T") - ada_boost = AdaBoost() - ada_boost.fit(tagged_table) - ada_boost.predict(tagged_table.features) - assert True # This asserts that the predict method succeeds - - -def test_ada_boost_predict_not_fitted() -> None: - table = Table.from_csv(resolve_resource_path("test_ada_boost.csv")) - tagged_table = TaggedTable(table, "T") - ada_boost = AdaBoost() - with pytest.raises(PredictionError): - ada_boost.predict(tagged_table.features) - - -def test_ada_boost_predict_invalid() -> None: - table = Table.from_csv(resolve_resource_path("test_ada_boost.csv")) - invalid_table = Table.from_csv(resolve_resource_path("test_ada_boost_invalid.csv")) - tagged_table = TaggedTable(table, "T") - invalid_tagged_table = TaggedTable(invalid_table, "T") - ada_boost = AdaBoost() - ada_boost.fit(tagged_table) - with pytest.raises(PredictionError): - ada_boost.predict(invalid_tagged_table.features) diff --git a/tests/safeds/ml/classification/_classifier/__init__.py b/tests/safeds/ml/classification/_classifier/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/safeds/ml/classification/_classifier/test_accuracy.py b/tests/safeds/ml/classification/_classifier/test_accuracy.py deleted file mode 100644 index ccb01bc32..000000000 --- a/tests/safeds/ml/classification/_classifier/test_accuracy.py +++ /dev/null @@ -1,20 +0,0 @@ -import pandas as pd -from safeds.data.tabular.containers import Column, Table, TaggedTable - -from ._dummy_classifier import DummyClassifier - - -def test_accuracy() -> None: - c1 = Column(pd.Series(data=[1, 2, 3, 4]), "predicted") - c2 = Column(pd.Series(data=[1, 2, 3, 3]), "expected") - table = TaggedTable(Table.from_columns([c1, c2]), target_name="expected") - - assert DummyClassifier().accuracy(table) == 0.75 - - -def test_accuracy_different_types() -> None: - c1 = Column(pd.Series(data=["1", "2", "3", "4"]), "predicted") - c2 = Column(pd.Series(data=[1, 2, 3, 3]), "expected") - table = TaggedTable(Table.from_columns([c1, c2]), target_name="expected") - - assert DummyClassifier().accuracy(table) == 0.0 diff --git a/tests/safeds/ml/classification/_decision_tree/__init__.py b/tests/safeds/ml/classification/_decision_tree/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/safeds/ml/classification/_decision_tree/test_fit.py b/tests/safeds/ml/classification/_decision_tree/test_fit.py deleted file mode 100644 index a700ba857..000000000 --- a/tests/safeds/ml/classification/_decision_tree/test_fit.py +++ /dev/null @@ -1,21 +0,0 @@ -import pytest -from safeds.data.tabular.containers import Table, TaggedTable -from safeds.exceptions import LearningError -from safeds.ml.classification import DecisionTree -from tests.fixtures import resolve_resource_path - - -def test_decision_tree_fit() -> None: - table = Table.from_csv(resolve_resource_path("test_decision_tree.csv")) - tagged_table = TaggedTable(table, "T") - decision_tree = DecisionTree() - decision_tree.fit(tagged_table) - assert True # This asserts that the fit method succeeds - - -def test_decision_tree_fit_invalid() -> None: - table = Table.from_csv(resolve_resource_path("test_decision_tree_invalid.csv")) - tagged_table = TaggedTable(table, "T") - decision_tree = DecisionTree() - with pytest.raises(LearningError): - decision_tree.fit(tagged_table) diff --git a/tests/safeds/ml/classification/_decision_tree/test_predict.py b/tests/safeds/ml/classification/_decision_tree/test_predict.py deleted file mode 100644 index cd1c98429..000000000 --- a/tests/safeds/ml/classification/_decision_tree/test_predict.py +++ /dev/null @@ -1,35 +0,0 @@ -import pytest -from safeds.data.tabular.containers import Table, TaggedTable -from safeds.exceptions import PredictionError -from safeds.ml.classification import DecisionTree -from tests.fixtures import resolve_resource_path - - -def test_decision_tree_predict() -> None: - table = Table.from_csv(resolve_resource_path("test_decision_tree.csv")) - tagged_table = TaggedTable(table, "T") - decision_tree = DecisionTree() - decision_tree.fit(tagged_table) - decision_tree.predict(tagged_table.features) - assert True # This asserts that the predict method succeeds - - -def test_decision_tree_predict_not_fitted() -> None: - table = Table.from_csv(resolve_resource_path("test_decision_tree.csv")) - tagged_table = TaggedTable(table, "T") - decision_tree = DecisionTree() - with pytest.raises(PredictionError): - decision_tree.predict(tagged_table.features) - - -def test_decision_tree_predict_invalid() -> None: - table = Table.from_csv(resolve_resource_path("test_decision_tree.csv")) - invalid_table = Table.from_csv( - resolve_resource_path("test_decision_tree_invalid.csv") - ) - tagged_table = TaggedTable(table, "T") - invalid_tagged_table = TaggedTable(invalid_table, "T") - decision_tree = DecisionTree() - decision_tree.fit(tagged_table) - with pytest.raises(PredictionError): - decision_tree.predict(invalid_tagged_table.features) diff --git a/tests/safeds/ml/classification/_gradient_boosting/__init__.py b/tests/safeds/ml/classification/_gradient_boosting/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/safeds/ml/classification/_gradient_boosting/test_fit.py b/tests/safeds/ml/classification/_gradient_boosting/test_fit.py deleted file mode 100644 index 9dc1e900b..000000000 --- a/tests/safeds/ml/classification/_gradient_boosting/test_fit.py +++ /dev/null @@ -1,25 +0,0 @@ -import pytest -from safeds.data.tabular.containers import Table, TaggedTable -from safeds.exceptions import LearningError -from safeds.ml.classification import GradientBoosting -from tests.fixtures import resolve_resource_path - - -def test_gradient_boosting_classification_fit() -> None: - table = Table.from_csv( - resolve_resource_path("test_gradient_boosting_classification.csv") - ) - tagged_table = TaggedTable(table, "T") - gradient_boosting_classification = GradientBoosting() - gradient_boosting_classification.fit(tagged_table) - assert True # This asserts that the fit method succeeds - - -def test_gradient_boosting_classification_fit_invalid() -> None: - table = Table.from_csv( - resolve_resource_path("test_gradient_boosting_classification_invalid.csv") - ) - tagged_table = TaggedTable(table, "T") - gradient_boosting_classification = GradientBoosting() - with pytest.raises(LearningError): - gradient_boosting_classification.fit(tagged_table) diff --git a/tests/safeds/ml/classification/_gradient_boosting/test_predict.py b/tests/safeds/ml/classification/_gradient_boosting/test_predict.py deleted file mode 100644 index e4f9e80f2..000000000 --- a/tests/safeds/ml/classification/_gradient_boosting/test_predict.py +++ /dev/null @@ -1,41 +0,0 @@ -import pytest -from safeds.data.tabular.containers import Table, TaggedTable -from safeds.exceptions import PredictionError -from safeds.ml.classification import GradientBoosting -from tests.fixtures import resolve_resource_path - - -def test_gradient_boosting_predict() -> None: - table = Table.from_csv( - resolve_resource_path("test_gradient_boosting_classification.csv") - ) - tagged_table = TaggedTable(table, "T") - gradient_boosting_classification = GradientBoosting() - gradient_boosting_classification.fit(tagged_table) - gradient_boosting_classification.predict(tagged_table.features) - assert True # This asserts that the predict method succeeds - - -def test_gradient_boosting_predict_not_fitted() -> None: - table = Table.from_csv( - resolve_resource_path("test_gradient_boosting_classification.csv") - ) - tagged_table = TaggedTable(table, "T") - gradient_boosting = GradientBoosting() - with pytest.raises(PredictionError): - gradient_boosting.predict(tagged_table.features) - - -def test_gradient_boosting_predict_invalid() -> None: - table = Table.from_csv( - resolve_resource_path("test_gradient_boosting_classification.csv") - ) - invalid_table = Table.from_csv( - resolve_resource_path("test_gradient_boosting_classification_invalid.csv") - ) - tagged_table = TaggedTable(table, "T") - invalid_tagged_table = TaggedTable(invalid_table, "T") - gradient_boosting = GradientBoosting() - gradient_boosting.fit(tagged_table) - with pytest.raises(PredictionError): - gradient_boosting.predict(invalid_tagged_table.features) diff --git a/tests/safeds/ml/classification/_k_nearest_neighbors/__init__.py b/tests/safeds/ml/classification/_k_nearest_neighbors/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/safeds/ml/classification/_k_nearest_neighbors/test_fit.py b/tests/safeds/ml/classification/_k_nearest_neighbors/test_fit.py deleted file mode 100644 index b74523b6b..000000000 --- a/tests/safeds/ml/classification/_k_nearest_neighbors/test_fit.py +++ /dev/null @@ -1,23 +0,0 @@ -import pytest -from safeds.data.tabular.containers import Table, TaggedTable -from safeds.exceptions import LearningError -from safeds.ml.classification import KNearestNeighbors as KNearestNeighborsClassifier -from tests.fixtures import resolve_resource_path - - -def test_k_nearest_neighbors_fit() -> None: - table = Table.from_csv(resolve_resource_path("test_k_nearest_neighbors.csv")) - tagged_table = TaggedTable(table, "T") - k_nearest_neighbors = KNearestNeighborsClassifier(2) - k_nearest_neighbors.fit(tagged_table) - assert True # This asserts that the fit method succeeds - - -def test_k_nearest_neighbors_fit_invalid() -> None: - table = Table.from_csv( - resolve_resource_path("test_k_nearest_neighbors_invalid.csv") - ) - tagged_table = TaggedTable(table, "T") - k_nearest_neighbors = KNearestNeighborsClassifier(2) - with pytest.raises(LearningError): - k_nearest_neighbors.fit(tagged_table) diff --git a/tests/safeds/ml/classification/_k_nearest_neighbors/test_predict.py b/tests/safeds/ml/classification/_k_nearest_neighbors/test_predict.py deleted file mode 100644 index 9e26b6e77..000000000 --- a/tests/safeds/ml/classification/_k_nearest_neighbors/test_predict.py +++ /dev/null @@ -1,35 +0,0 @@ -import pytest -from safeds.data.tabular.containers import Table, TaggedTable -from safeds.exceptions import PredictionError -from safeds.ml.classification import KNearestNeighbors as KNearestNeighborsClassifier -from tests.fixtures import resolve_resource_path - - -def test_k_nearest_neighbors_predict() -> None: - table = Table.from_csv(resolve_resource_path("test_k_nearest_neighbors.csv")) - tagged_table = TaggedTable(table, "T") - k_nearest_neighbors = KNearestNeighborsClassifier(2) - k_nearest_neighbors.fit(tagged_table) - k_nearest_neighbors.predict(tagged_table.features) - assert True # This asserts that the predict method succeeds - - -def test_k_nearest_neighbors_predict_not_fitted() -> None: - table = Table.from_csv(resolve_resource_path("test_k_nearest_neighbors.csv")) - tagged_table = TaggedTable(table, "T") - k_nearest_neighbors = KNearestNeighborsClassifier(2) - with pytest.raises(PredictionError): - k_nearest_neighbors.predict(tagged_table.features) - - -def test_k_nearest_neighbors_predict_invalid() -> None: - table = Table.from_csv(resolve_resource_path("test_k_nearest_neighbors.csv")) - invalid_table = Table.from_csv( - resolve_resource_path("test_k_nearest_neighbors_invalid.csv") - ) - tagged_table = TaggedTable(table, "T") - invalid_tagged_table = TaggedTable(invalid_table, "T") - k_nearest_neighbors = KNearestNeighborsClassifier(2) - k_nearest_neighbors.fit(tagged_table) - with pytest.raises(PredictionError): - k_nearest_neighbors.predict(invalid_tagged_table.features) diff --git a/tests/safeds/ml/classification/_logistic_regression/__init__.py b/tests/safeds/ml/classification/_logistic_regression/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/safeds/ml/classification/_logistic_regression/test_fit.py b/tests/safeds/ml/classification/_logistic_regression/test_fit.py deleted file mode 100644 index 292538c89..000000000 --- a/tests/safeds/ml/classification/_logistic_regression/test_fit.py +++ /dev/null @@ -1,23 +0,0 @@ -import pytest -from safeds.data.tabular.containers import Table, TaggedTable -from safeds.exceptions import LearningError -from safeds.ml.classification import LogisticRegression -from tests.fixtures import resolve_resource_path - - -def test_logistic_regression_fit() -> None: - table = Table.from_csv(resolve_resource_path("test_logistic_regression.csv")) - tagged_table = TaggedTable(table, "T") - log_regression = LogisticRegression() - log_regression.fit(tagged_table) - assert True # This asserts that the fit method succeeds - - -def test_logistic_regression_fit_invalid() -> None: - table = Table.from_csv( - resolve_resource_path("test_logistic_regression_invalid.csv") - ) - tagged_table = TaggedTable(table, "T") - log_regression = LogisticRegression() - with pytest.raises(LearningError): - log_regression.fit(tagged_table) diff --git a/tests/safeds/ml/classification/_logistic_regression/test_predict.py b/tests/safeds/ml/classification/_logistic_regression/test_predict.py deleted file mode 100644 index 05fd12c45..000000000 --- a/tests/safeds/ml/classification/_logistic_regression/test_predict.py +++ /dev/null @@ -1,35 +0,0 @@ -import pytest -from safeds.data.tabular.containers import Table, TaggedTable -from safeds.exceptions import PredictionError -from safeds.ml.classification import LogisticRegression -from tests.fixtures import resolve_resource_path - - -def test_logistic_regression_predict() -> None: - table = Table.from_csv(resolve_resource_path("test_logistic_regression.csv")) - tagged_table = TaggedTable(table, "T") - log_regression = LogisticRegression() - log_regression.fit(tagged_table) - log_regression.predict(tagged_table.features) - assert True # This asserts that the predict method succeeds - - -def test_logistic_regression_predict_not_fitted() -> None: - table = Table.from_csv(resolve_resource_path("test_logistic_regression.csv")) - tagged_table = TaggedTable(table, "T") - log_regression = LogisticRegression() - with pytest.raises(PredictionError): - log_regression.predict(tagged_table.features) - - -def test_logistic_regression_predict_invalid() -> None: - table = Table.from_csv(resolve_resource_path("test_logistic_regression.csv")) - invalid_table = Table.from_csv( - resolve_resource_path("test_logistic_regression_invalid.csv") - ) - tagged_table = TaggedTable(table, "T") - invalid_tagged_table = TaggedTable(invalid_table, "T") - log_regression = LogisticRegression() - log_regression.fit(tagged_table) - with pytest.raises(PredictionError): - log_regression.predict(invalid_tagged_table.features) diff --git a/tests/safeds/ml/classification/_random_forest/__init__.py b/tests/safeds/ml/classification/_random_forest/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/safeds/ml/classification/_random_forest/test_fit.py b/tests/safeds/ml/classification/_random_forest/test_fit.py deleted file mode 100644 index f94fea4bb..000000000 --- a/tests/safeds/ml/classification/_random_forest/test_fit.py +++ /dev/null @@ -1,21 +0,0 @@ -import pytest -from safeds.data.tabular.containers import Table, TaggedTable -from safeds.exceptions import LearningError -from safeds.ml.classification import RandomForest as RandomForestClassifier -from tests.fixtures import resolve_resource_path - - -def test_logistic_regression_fit() -> None: - table = Table.from_csv(resolve_resource_path("test_random_forest.csv")) - tagged_table = TaggedTable(table, "T") - random_forest = RandomForestClassifier() - random_forest.fit(tagged_table) - assert True # This asserts that the fit method succeeds - - -def test_logistic_regression_fit_invalid() -> None: - table = Table.from_csv(resolve_resource_path("test_random_forest_invalid.csv")) - tagged_table = TaggedTable(table, "T") - random_forest = RandomForestClassifier() - with pytest.raises(LearningError): - random_forest.fit(tagged_table) diff --git a/tests/safeds/ml/classification/_random_forest/test_predict.py b/tests/safeds/ml/classification/_random_forest/test_predict.py deleted file mode 100644 index 6c5a5d922..000000000 --- a/tests/safeds/ml/classification/_random_forest/test_predict.py +++ /dev/null @@ -1,35 +0,0 @@ -import pytest -from safeds.data.tabular.containers import Table, TaggedTable -from safeds.exceptions import PredictionError -from safeds.ml.classification import RandomForest as RandomForestClassifier -from tests.fixtures import resolve_resource_path - - -def test_random_forest_predict() -> None: - table = Table.from_csv(resolve_resource_path("test_random_forest.csv")) - tagged_table = TaggedTable(table, "T") - random_forest = RandomForestClassifier() - random_forest.fit(tagged_table) - random_forest.predict(tagged_table.features) - assert True # This asserts that the predict method succeeds - - -def test_random_forest_predict_not_fitted() -> None: - table = Table.from_csv(resolve_resource_path("test_random_forest.csv")) - tagged_table = TaggedTable(table, "T") - random_forest = RandomForestClassifier() - with pytest.raises(PredictionError): - random_forest.predict(tagged_table.features) - - -def test_random_forest_predict_invalid() -> None: - table = Table.from_csv(resolve_resource_path("test_random_forest.csv")) - invalid_table = Table.from_csv( - resolve_resource_path("test_random_forest_invalid.csv") - ) - tagged_table = TaggedTable(table, "T") - invalid_tagged_table = TaggedTable(invalid_table, "T") - random_forest = RandomForestClassifier() - random_forest.fit(tagged_table) - with pytest.raises(PredictionError): - random_forest.predict(invalid_tagged_table.features) diff --git a/tests/safeds/ml/classification/test_ada_boost.py b/tests/safeds/ml/classification/test_ada_boost.py new file mode 100644 index 000000000..0989ffdba --- /dev/null +++ b/tests/safeds/ml/classification/test_ada_boost.py @@ -0,0 +1,58 @@ +import pytest +from safeds.data.tabular.containers import Table, TaggedTable +from safeds.exceptions import LearningError, PredictionError +from safeds.ml.classification import AdaBoost, Classifier +from tests.fixtures import resolve_resource_path + + +@pytest.fixture() +def classifier() -> Classifier: + return AdaBoost() + + +@pytest.fixture() +def valid_data() -> TaggedTable: + table = Table.from_csv(resolve_resource_path("test_ada_boost.csv")) + return TaggedTable(table, "T") + + +@pytest.fixture() +def invalid_data() -> TaggedTable: + table = Table.from_csv(resolve_resource_path("test_ada_boost_invalid.csv")) + return TaggedTable(table, "T") + + +class TestFit: + def test_should_succeed_on_valid_data( + self, classifier: Classifier, valid_data: TaggedTable + ) -> None: + classifier.fit(valid_data) + assert True # This asserts that the fit method succeeds + + def test_should_raise_on_invalid_data( + self, classifier: Classifier, invalid_data: TaggedTable + ) -> None: + with pytest.raises(LearningError): + classifier.fit(invalid_data) + + +class TestPredict: + def test_should_succeed_on_valid_data( + self, classifier: Classifier, valid_data: TaggedTable + ) -> None: + classifier.fit(valid_data) + classifier.predict(valid_data.features) + assert True # This asserts that the predict method succeeds + + def test_should_raise_when_not_fitted( + self, classifier: Classifier, valid_data: TaggedTable + ) -> None: + with pytest.raises(PredictionError): + classifier.predict(valid_data.features) + + def test_should_raise_on_invalid_data( + self, classifier: Classifier, valid_data: TaggedTable, invalid_data: TaggedTable + ) -> None: + classifier.fit(valid_data) + with pytest.raises(PredictionError): + classifier.predict(invalid_data.features) diff --git a/tests/safeds/ml/classification/_classifier/_dummy_classifier.py b/tests/safeds/ml/classification/test_classifier.py similarity index 50% rename from tests/safeds/ml/classification/_classifier/_dummy_classifier.py rename to tests/safeds/ml/classification/test_classifier.py index 60bb7859a..314b675ea 100644 --- a/tests/safeds/ml/classification/_classifier/_dummy_classifier.py +++ b/tests/safeds/ml/classification/test_classifier.py @@ -1,4 +1,5 @@ -from safeds.data.tabular.containers import Table, TaggedTable +import pandas as pd +from safeds.data.tabular.containers import Column, Table, TaggedTable from safeds.ml.classification import Classifier @@ -24,3 +25,19 @@ def predict(self, dataset: Table) -> TaggedTable: dataset = Table.from_columns([feature, predicted]) return TaggedTable(dataset, target_name="predicted") + + +class TestAccuracy: + def test_with_same_type(self) -> None: + c1 = Column(pd.Series(data=[1, 2, 3, 4]), "predicted") + c2 = Column(pd.Series(data=[1, 2, 3, 3]), "expected") + table = TaggedTable(Table.from_columns([c1, c2]), target_name="expected") + + assert DummyClassifier().accuracy(table) == 0.75 + + def test_with_different_types(self) -> None: + c1 = Column(pd.Series(data=["1", "2", "3", "4"]), "predicted") + c2 = Column(pd.Series(data=[1, 2, 3, 3]), "expected") + table = TaggedTable(Table.from_columns([c1, c2]), target_name="expected") + + assert DummyClassifier().accuracy(table) == 0.0 diff --git a/tests/safeds/ml/classification/test_decision_tree.py b/tests/safeds/ml/classification/test_decision_tree.py new file mode 100644 index 000000000..091ff7f8c --- /dev/null +++ b/tests/safeds/ml/classification/test_decision_tree.py @@ -0,0 +1,58 @@ +import pytest +from safeds.data.tabular.containers import Table, TaggedTable +from safeds.exceptions import LearningError, PredictionError +from safeds.ml.classification import Classifier, DecisionTree +from tests.fixtures import resolve_resource_path + + +@pytest.fixture() +def classifier() -> Classifier: + return DecisionTree() + + +@pytest.fixture() +def valid_data() -> TaggedTable: + table = Table.from_csv(resolve_resource_path("test_decision_tree.csv")) + return TaggedTable(table, "T") + + +@pytest.fixture() +def invalid_data() -> TaggedTable: + table = Table.from_csv(resolve_resource_path("test_decision_tree_invalid.csv")) + return TaggedTable(table, "T") + + +class TestFit: + def test_should_succeed_on_valid_data( + self, classifier: Classifier, valid_data: TaggedTable + ) -> None: + classifier.fit(valid_data) + assert True # This asserts that the fit method succeeds + + def test_should_raise_on_invalid_data( + self, classifier: Classifier, invalid_data: TaggedTable + ) -> None: + with pytest.raises(LearningError): + classifier.fit(invalid_data) + + +class TestPredict: + def test_should_succeed_on_valid_data( + self, classifier: Classifier, valid_data: TaggedTable + ) -> None: + classifier.fit(valid_data) + classifier.predict(valid_data.features) + assert True # This asserts that the predict method succeeds + + def test_should_raise_when_not_fitted( + self, classifier: Classifier, valid_data: TaggedTable + ) -> None: + with pytest.raises(PredictionError): + classifier.predict(valid_data.features) + + def test_should_raise_on_invalid_data( + self, classifier: Classifier, valid_data: TaggedTable, invalid_data: TaggedTable + ) -> None: + classifier.fit(valid_data) + with pytest.raises(PredictionError): + classifier.predict(invalid_data.features) diff --git a/tests/safeds/ml/classification/test_gradient_boosting.py b/tests/safeds/ml/classification/test_gradient_boosting.py new file mode 100644 index 000000000..c820c62b8 --- /dev/null +++ b/tests/safeds/ml/classification/test_gradient_boosting.py @@ -0,0 +1,62 @@ +import pytest +from safeds.data.tabular.containers import Table, TaggedTable +from safeds.exceptions import LearningError, PredictionError +from safeds.ml.classification import Classifier, GradientBoosting +from tests.fixtures import resolve_resource_path + + +@pytest.fixture() +def classifier() -> Classifier: + return GradientBoosting() + + +@pytest.fixture() +def valid_data() -> TaggedTable: + table = Table.from_csv( + resolve_resource_path("test_gradient_boosting_classification.csv") + ) + return TaggedTable(table, "T") + + +@pytest.fixture() +def invalid_data() -> TaggedTable: + table = Table.from_csv( + resolve_resource_path("test_gradient_boosting_classification_invalid.csv") + ) + return TaggedTable(table, "T") + + +class TestFit: + def test_should_succeed_on_valid_data( + self, classifier: Classifier, valid_data: TaggedTable + ) -> None: + classifier.fit(valid_data) + assert True # This asserts that the fit method succeeds + + def test_should_raise_on_invalid_data( + self, classifier: Classifier, invalid_data: TaggedTable + ) -> None: + with pytest.raises(LearningError): + classifier.fit(invalid_data) + + +class TestPredict: + def test_should_succeed_on_valid_data( + self, classifier: Classifier, valid_data: TaggedTable + ) -> None: + classifier.fit(valid_data) + classifier.predict(valid_data.features) + assert True # This asserts that the predict method succeeds + + def test_should_raise_when_not_fitted( + self, classifier: Classifier, valid_data: TaggedTable + ) -> None: + with pytest.raises(PredictionError): + classifier.predict(valid_data.features) + + def test_should_raise_on_invalid_data( + self, classifier: Classifier, valid_data: TaggedTable, invalid_data: TaggedTable + ) -> None: + classifier.fit(valid_data) + with pytest.raises(PredictionError): + classifier.predict(invalid_data.features) diff --git a/tests/safeds/ml/classification/test_k_nearest_neighbors.py b/tests/safeds/ml/classification/test_k_nearest_neighbors.py new file mode 100644 index 000000000..c202248bb --- /dev/null +++ b/tests/safeds/ml/classification/test_k_nearest_neighbors.py @@ -0,0 +1,60 @@ +import pytest +from safeds.data.tabular.containers import Table, TaggedTable +from safeds.exceptions import LearningError, PredictionError +from safeds.ml.classification import Classifier, KNearestNeighbors +from tests.fixtures import resolve_resource_path + + +@pytest.fixture() +def classifier() -> Classifier: + return KNearestNeighbors(2) + + +@pytest.fixture() +def valid_data() -> TaggedTable: + table = Table.from_csv(resolve_resource_path("test_k_nearest_neighbors.csv")) + return TaggedTable(table, "T") + + +@pytest.fixture() +def invalid_data() -> TaggedTable: + table = Table.from_csv( + resolve_resource_path("test_k_nearest_neighbors_invalid.csv") + ) + return TaggedTable(table, "T") + + +class TestFit: + def test_should_succeed_on_valid_data( + self, classifier: Classifier, valid_data: TaggedTable + ) -> None: + classifier.fit(valid_data) + assert True # This asserts that the fit method succeeds + + def test_should_raise_on_invalid_data( + self, classifier: Classifier, invalid_data: TaggedTable + ) -> None: + with pytest.raises(LearningError): + classifier.fit(invalid_data) + + +class TestPredict: + def test_should_succeed_on_valid_data( + self, classifier: Classifier, valid_data: TaggedTable + ) -> None: + classifier.fit(valid_data) + classifier.predict(valid_data.features) + assert True # This asserts that the predict method succeeds + + def test_should_raise_when_not_fitted( + self, classifier: Classifier, valid_data: TaggedTable + ) -> None: + with pytest.raises(PredictionError): + classifier.predict(valid_data.features) + + def test_should_raise_on_invalid_data( + self, classifier: Classifier, valid_data: TaggedTable, invalid_data: TaggedTable + ) -> None: + classifier.fit(valid_data) + with pytest.raises(PredictionError): + classifier.predict(invalid_data.features) diff --git a/tests/safeds/ml/classification/test_logistic_regression.py b/tests/safeds/ml/classification/test_logistic_regression.py new file mode 100644 index 000000000..936f8beae --- /dev/null +++ b/tests/safeds/ml/classification/test_logistic_regression.py @@ -0,0 +1,60 @@ +import pytest +from safeds.data.tabular.containers import Table, TaggedTable +from safeds.exceptions import LearningError, PredictionError +from safeds.ml.classification import Classifier, LogisticRegression +from tests.fixtures import resolve_resource_path + + +@pytest.fixture() +def classifier() -> Classifier: + return LogisticRegression() + + +@pytest.fixture() +def valid_data() -> TaggedTable: + table = Table.from_csv(resolve_resource_path("test_logistic_regression.csv")) + return TaggedTable(table, "T") + + +@pytest.fixture() +def invalid_data() -> TaggedTable: + table = Table.from_csv( + resolve_resource_path("test_logistic_regression_invalid.csv") + ) + return TaggedTable(table, "T") + + +class TestFit: + def test_should_succeed_on_valid_data( + self, classifier: Classifier, valid_data: TaggedTable + ) -> None: + classifier.fit(valid_data) + assert True # This asserts that the fit method succeeds + + def test_should_raise_on_invalid_data( + self, classifier: Classifier, invalid_data: TaggedTable + ) -> None: + with pytest.raises(LearningError): + classifier.fit(invalid_data) + + +class TestPredict: + def test_should_succeed_on_valid_data( + self, classifier: Classifier, valid_data: TaggedTable + ) -> None: + classifier.fit(valid_data) + classifier.predict(valid_data.features) + assert True # This asserts that the predict method succeeds + + def test_should_raise_when_not_fitted( + self, classifier: Classifier, valid_data: TaggedTable + ) -> None: + with pytest.raises(PredictionError): + classifier.predict(valid_data.features) + + def test_should_raise_on_invalid_data( + self, classifier: Classifier, valid_data: TaggedTable, invalid_data: TaggedTable + ) -> None: + classifier.fit(valid_data) + with pytest.raises(PredictionError): + classifier.predict(invalid_data.features) diff --git a/tests/safeds/ml/classification/test_random_forest.py b/tests/safeds/ml/classification/test_random_forest.py new file mode 100644 index 000000000..df0da59a9 --- /dev/null +++ b/tests/safeds/ml/classification/test_random_forest.py @@ -0,0 +1,58 @@ +import pytest +from safeds.data.tabular.containers import Table, TaggedTable +from safeds.exceptions import LearningError, PredictionError +from safeds.ml.classification import Classifier, RandomForest +from tests.fixtures import resolve_resource_path + + +@pytest.fixture() +def classifier() -> Classifier: + return RandomForest() + + +@pytest.fixture() +def valid_data() -> TaggedTable: + table = Table.from_csv(resolve_resource_path("test_random_forest.csv")) + return TaggedTable(table, "T") + + +@pytest.fixture() +def invalid_data() -> TaggedTable: + table = Table.from_csv(resolve_resource_path("test_random_forest_invalid.csv")) + return TaggedTable(table, "T") + + +class TestFit: + def test_should_succeed_on_valid_data( + self, classifier: Classifier, valid_data: TaggedTable + ) -> None: + classifier.fit(valid_data) + assert True # This asserts that the fit method succeeds + + def test_should_raise_on_invalid_data( + self, classifier: Classifier, invalid_data: TaggedTable + ) -> None: + with pytest.raises(LearningError): + classifier.fit(invalid_data) + + +class TestPredict: + def test_should_succeed_on_valid_data( + self, classifier: Classifier, valid_data: TaggedTable + ) -> None: + classifier.fit(valid_data) + classifier.predict(valid_data.features) + assert True # This asserts that the predict method succeeds + + def test_should_raise_when_not_fitted( + self, classifier: Classifier, valid_data: TaggedTable + ) -> None: + with pytest.raises(PredictionError): + classifier.predict(valid_data.features) + + def test_should_raise_on_invalid_data( + self, classifier: Classifier, valid_data: TaggedTable, invalid_data: TaggedTable + ) -> None: + classifier.fit(valid_data) + with pytest.raises(PredictionError): + classifier.predict(invalid_data.features) diff --git a/tests/safeds/ml/regression/_ada_boost/__init__.py b/tests/safeds/ml/regression/_ada_boost/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/safeds/ml/regression/_ada_boost/test_fit.py b/tests/safeds/ml/regression/_ada_boost/test_fit.py deleted file mode 100644 index 9d5c063df..000000000 --- a/tests/safeds/ml/regression/_ada_boost/test_fit.py +++ /dev/null @@ -1,21 +0,0 @@ -import pytest -from safeds.data.tabular.containers import Table, TaggedTable -from safeds.exceptions import LearningError -from safeds.ml.regression import AdaBoost -from tests.fixtures import resolve_resource_path - - -def test_ada_boost_fit() -> None: - table = Table.from_csv(resolve_resource_path("test_ada_boost.csv")) - tagged_table = TaggedTable(table, "T") - ada_boost = AdaBoost() - ada_boost.fit(tagged_table) - assert True # This asserts that the fit method succeeds - - -def test_ada_boost_fit_invalid() -> None: - table = Table.from_csv(resolve_resource_path("test_ada_boost_invalid.csv")) - tagged_table = TaggedTable(table, "T") - ada_boost = AdaBoost() - with pytest.raises(LearningError): - ada_boost.fit(tagged_table) diff --git a/tests/safeds/ml/regression/_ada_boost/test_predict.py b/tests/safeds/ml/regression/_ada_boost/test_predict.py deleted file mode 100644 index a1e1e3c1f..000000000 --- a/tests/safeds/ml/regression/_ada_boost/test_predict.py +++ /dev/null @@ -1,33 +0,0 @@ -import pytest -from safeds.data.tabular.containers import Table, TaggedTable -from safeds.exceptions import PredictionError -from safeds.ml.regression import AdaBoost -from tests.fixtures import resolve_resource_path - - -def test_ada_boost_predict() -> None: - table = Table.from_csv(resolve_resource_path("test_ada_boost.csv")) - tagged_table = TaggedTable(table, "T") - ada_boost = AdaBoost() - ada_boost.fit(tagged_table) - ada_boost.predict(tagged_table.features) - assert True # This asserts that the predict method succeeds - - -def test_ada_boost_predict_not_fitted() -> None: - table = Table.from_csv(resolve_resource_path("test_ada_boost.csv")) - tagged_table = TaggedTable(table, "T") - ada_boost = AdaBoost() - with pytest.raises(PredictionError): - ada_boost.predict(tagged_table.features) - - -def test_ada_boost_predict_invalid() -> None: - table = Table.from_csv(resolve_resource_path("test_ada_boost.csv")) - invalid_table = Table.from_csv(resolve_resource_path("test_ada_boost_invalid.csv")) - tagged_table = TaggedTable(table, "T") - invalid_tagged_table = TaggedTable(invalid_table, "T") - ada_boost = AdaBoost() - ada_boost.fit(tagged_table) - with pytest.raises(PredictionError): - ada_boost.predict(invalid_tagged_table.features) diff --git a/tests/safeds/ml/regression/_decision_tree/__init__.py b/tests/safeds/ml/regression/_decision_tree/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/safeds/ml/regression/_decision_tree/test_fit.py b/tests/safeds/ml/regression/_decision_tree/test_fit.py deleted file mode 100644 index 691b09172..000000000 --- a/tests/safeds/ml/regression/_decision_tree/test_fit.py +++ /dev/null @@ -1,21 +0,0 @@ -import pytest -from safeds.data.tabular.containers import Table, TaggedTable -from safeds.exceptions import LearningError -from safeds.ml.regression import DecisionTree -from tests.fixtures import resolve_resource_path - - -def test_decision_tree_fit() -> None: - table = Table.from_csv(resolve_resource_path("test_decision_tree.csv")) - tagged_table = TaggedTable(table, "T") - decision_tree = DecisionTree() - decision_tree.fit(tagged_table) - assert True # This asserts that the fit method succeeds - - -def test_decision_tree_fit_invalid() -> None: - table = Table.from_csv(resolve_resource_path("test_decision_tree_invalid.csv")) - tagged_table = TaggedTable(table, "T") - decision_tree = DecisionTree() - with pytest.raises(LearningError): - decision_tree.fit(tagged_table) diff --git a/tests/safeds/ml/regression/_decision_tree/test_predict.py b/tests/safeds/ml/regression/_decision_tree/test_predict.py deleted file mode 100644 index 98d4f2fa2..000000000 --- a/tests/safeds/ml/regression/_decision_tree/test_predict.py +++ /dev/null @@ -1,35 +0,0 @@ -import pytest -from safeds.data.tabular.containers import Table, TaggedTable -from safeds.exceptions import PredictionError -from safeds.ml.regression import DecisionTree -from tests.fixtures import resolve_resource_path - - -def test_decision_tree_predict() -> None: - table = Table.from_csv(resolve_resource_path("test_decision_tree.csv")) - tagged_table = TaggedTable(table, "T") - decision_tree = DecisionTree() - decision_tree.fit(tagged_table) - decision_tree.predict(tagged_table.features) - assert True # This asserts that the predict method succeeds - - -def test_decision_tree_predict_not_fitted() -> None: - table = Table.from_csv(resolve_resource_path("test_decision_tree.csv")) - tagged_table = TaggedTable(table, "T") - decision_tree = DecisionTree() - with pytest.raises(PredictionError): - decision_tree.predict(tagged_table.features) - - -def test_decision_tree_predict_invalid() -> None: - table = Table.from_csv(resolve_resource_path("test_decision_tree.csv")) - invalid_table = Table.from_csv( - resolve_resource_path("test_decision_tree_invalid.csv") - ) - tagged_table = TaggedTable(table, "T") - invalid_tagged_table = TaggedTable(invalid_table, "T") - decision_tree = DecisionTree() - decision_tree.fit(tagged_table) - with pytest.raises(PredictionError): - decision_tree.predict(invalid_tagged_table.features) diff --git a/tests/safeds/ml/regression/_elastic_net/__init__.py b/tests/safeds/ml/regression/_elastic_net/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/safeds/ml/regression/_elastic_net/test_fit.py b/tests/safeds/ml/regression/_elastic_net/test_fit.py deleted file mode 100644 index 1a12812e1..000000000 --- a/tests/safeds/ml/regression/_elastic_net/test_fit.py +++ /dev/null @@ -1,23 +0,0 @@ -import pytest -from safeds.data.tabular.containers import Table, TaggedTable -from safeds.exceptions import LearningError -from safeds.ml.regression import ElasticNetRegression -from tests.fixtures import resolve_resource_path - - -def test_elastic_net_regression_fit() -> None: - table = Table.from_csv(resolve_resource_path("test_elastic_net_regression.csv")) - tagged_table = TaggedTable(table, "T") - en_regression = ElasticNetRegression() - en_regression.fit(tagged_table) - assert True # This asserts that the fit method succeeds - - -def test_elastic_net_regression_fit_invalid() -> None: - table = Table.from_csv( - resolve_resource_path("test_elastic_net_regression_invalid.csv") - ) - tagged_table = TaggedTable(table, "T") - en_regression = ElasticNetRegression() - with pytest.raises(LearningError): - en_regression.fit(tagged_table) diff --git a/tests/safeds/ml/regression/_elastic_net/test_predict.py b/tests/safeds/ml/regression/_elastic_net/test_predict.py deleted file mode 100644 index a81d269e0..000000000 --- a/tests/safeds/ml/regression/_elastic_net/test_predict.py +++ /dev/null @@ -1,35 +0,0 @@ -import pytest -from safeds.data.tabular.containers import Table, TaggedTable -from safeds.exceptions import PredictionError -from safeds.ml.regression import ElasticNetRegression -from tests.fixtures import resolve_resource_path - - -def test_elastic_net_regression_predict() -> None: - table = Table.from_csv(resolve_resource_path("test_elastic_net_regression.csv")) - tagged_table = TaggedTable(table, "T") - en_regression = ElasticNetRegression() - en_regression.fit(tagged_table) - en_regression.predict(tagged_table.features) - assert True # This asserts that the predict method succeeds - - -def test_elastic_net_regression_predict_not_fitted() -> None: - table = Table.from_csv(resolve_resource_path("test_elastic_net_regression.csv")) - tagged_table = TaggedTable(table, "T") - en_regression = ElasticNetRegression() - with pytest.raises(PredictionError): - en_regression.predict(tagged_table.features) - - -def test_elastic_net_regression_predict_invalid() -> None: - table = Table.from_csv(resolve_resource_path("test_elastic_net_regression.csv")) - invalid_table = Table.from_csv( - resolve_resource_path("test_elastic_net_regression_invalid.csv") - ) - tagged_table = TaggedTable(table, "T") - invalid_tagged_table = TaggedTable(invalid_table, "T") - en_regression = ElasticNetRegression() - en_regression.fit(tagged_table) - with pytest.raises(PredictionError): - en_regression.predict(invalid_tagged_table.features) diff --git a/tests/safeds/ml/regression/_gradient_boosting_regression/__init__.py b/tests/safeds/ml/regression/_gradient_boosting_regression/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/safeds/ml/regression/_gradient_boosting_regression/test_fit.py b/tests/safeds/ml/regression/_gradient_boosting_regression/test_fit.py deleted file mode 100644 index 17fd983fd..000000000 --- a/tests/safeds/ml/regression/_gradient_boosting_regression/test_fit.py +++ /dev/null @@ -1,25 +0,0 @@ -import pytest -from safeds.data.tabular.containers import Table, TaggedTable -from safeds.exceptions import LearningError -from safeds.ml.regression import GradientBoosting -from tests.fixtures import resolve_resource_path - - -def test_gradient_boosting_regression_fit() -> None: - table = Table.from_csv( - resolve_resource_path("test_gradient_boosting_regression.csv") - ) - tagged_table = TaggedTable(table, "T") - gradient_boosting = GradientBoosting() - gradient_boosting.fit(tagged_table) - assert True # This asserts that the fit method succeeds - - -def test_gradient_boosting_regression_fit_invalid() -> None: - table = Table.from_csv( - resolve_resource_path("test_gradient_boosting_regression_invalid.csv") - ) - tagged_table = TaggedTable(table, "T") - gradient_boosting_regression = GradientBoosting() - with pytest.raises(LearningError): - gradient_boosting_regression.fit(tagged_table) diff --git a/tests/safeds/ml/regression/_gradient_boosting_regression/test_predict.py b/tests/safeds/ml/regression/_gradient_boosting_regression/test_predict.py deleted file mode 100644 index c61b89b97..000000000 --- a/tests/safeds/ml/regression/_gradient_boosting_regression/test_predict.py +++ /dev/null @@ -1,41 +0,0 @@ -import pytest -from safeds.data.tabular.containers import Table, TaggedTable -from safeds.exceptions import PredictionError -from safeds.ml.regression import GradientBoosting -from tests.fixtures import resolve_resource_path - - -def test_gradient_boosting_predict() -> None: - table = Table.from_csv( - resolve_resource_path("test_gradient_boosting_regression.csv") - ) - tagged_table = TaggedTable(table, "T") - gradient_boosting_regression = GradientBoosting() - gradient_boosting_regression.fit(tagged_table) - gradient_boosting_regression.predict(tagged_table.features) - assert True # This asserts that the predict method succeeds - - -def test_gradient_boosting_predict_not_fitted() -> None: - table = Table.from_csv( - resolve_resource_path("test_gradient_boosting_regression.csv") - ) - tagged_table = TaggedTable(table, "T") - gradient_boosting_regression = GradientBoosting() - with pytest.raises(PredictionError): - gradient_boosting_regression.predict(tagged_table.features) - - -def test_gradient_boosting_predict_invalid() -> None: - table = Table.from_csv( - resolve_resource_path("test_gradient_boosting_regression.csv") - ) - invalid_table = Table.from_csv( - resolve_resource_path("test_gradient_boosting_regression_invalid.csv") - ) - tagged_table = TaggedTable(table, "T") - invalid_tagged_table = TaggedTable(invalid_table, "T") - gradient_boosting_regression = GradientBoosting() - gradient_boosting_regression.fit(tagged_table) - with pytest.raises(PredictionError): - gradient_boosting_regression.predict(invalid_tagged_table.features) diff --git a/tests/safeds/ml/regression/_k_nearest_neighbors/__init__.py b/tests/safeds/ml/regression/_k_nearest_neighbors/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/safeds/ml/regression/_k_nearest_neighbors/test_fit.py b/tests/safeds/ml/regression/_k_nearest_neighbors/test_fit.py deleted file mode 100644 index 57691be21..000000000 --- a/tests/safeds/ml/regression/_k_nearest_neighbors/test_fit.py +++ /dev/null @@ -1,23 +0,0 @@ -import pytest -from safeds.data.tabular.containers import Table, TaggedTable -from safeds.exceptions import LearningError -from safeds.ml.regression import KNearestNeighbors as KNearestNeighborsRegressor -from tests.fixtures import resolve_resource_path - - -def test_k_nearest_neighbors_fit() -> None: - table = Table.from_csv(resolve_resource_path("test_k_nearest_neighbors.csv")) - tagged_table = TaggedTable(table, "T") - k_nearest_neighbors = KNearestNeighborsRegressor(2) - k_nearest_neighbors.fit(tagged_table) - assert True # This asserts that the fit method succeeds - - -def test_k_nearest_neighbors_fit_invalid() -> None: - table = Table.from_csv( - resolve_resource_path("test_k_nearest_neighbors_invalid.csv") - ) - tagged_table = TaggedTable(table, "T") - k_nearest_neighbors = KNearestNeighborsRegressor(2) - with pytest.raises(LearningError): - k_nearest_neighbors.fit(tagged_table) diff --git a/tests/safeds/ml/regression/_k_nearest_neighbors/test_predict.py b/tests/safeds/ml/regression/_k_nearest_neighbors/test_predict.py deleted file mode 100644 index 9f870c1c7..000000000 --- a/tests/safeds/ml/regression/_k_nearest_neighbors/test_predict.py +++ /dev/null @@ -1,35 +0,0 @@ -import pytest -from safeds.data.tabular.containers import Table, TaggedTable -from safeds.exceptions import PredictionError -from safeds.ml.regression import KNearestNeighbors as KNearestNeighborsRegressor -from tests.fixtures import resolve_resource_path - - -def test_k_nearest_neighbors_predict() -> None: - table = Table.from_csv(resolve_resource_path("test_k_nearest_neighbors.csv")) - tagged_table = TaggedTable(table, "T") - k_nearest_neighbors = KNearestNeighborsRegressor(2) - k_nearest_neighbors.fit(tagged_table) - k_nearest_neighbors.predict(tagged_table.features) - assert True # This asserts that the predict method succeeds - - -def test_k_nearest_neighbors_predict_not_fitted() -> None: - table = Table.from_csv(resolve_resource_path("test_k_nearest_neighbors.csv")) - tagged_table = TaggedTable(table, "T") - k_nearest_neighbors = KNearestNeighborsRegressor(2) - with pytest.raises(PredictionError): - k_nearest_neighbors.predict(tagged_table.features) - - -def test_k_nearest_neighbors_predict_invalid() -> None: - table = Table.from_csv(resolve_resource_path("test_k_nearest_neighbors.csv")) - invalid_table = Table.from_csv( - resolve_resource_path("test_k_nearest_neighbors_invalid.csv") - ) - tagged_table = TaggedTable(table, "T") - invalid_tagged_table = TaggedTable(invalid_table, "T") - k_nearest_neighbors = KNearestNeighborsRegressor(2) - k_nearest_neighbors.fit(tagged_table) - with pytest.raises(PredictionError): - k_nearest_neighbors.predict(invalid_tagged_table.features) diff --git a/tests/safeds/ml/regression/_lasso_regression/__init__.py b/tests/safeds/ml/regression/_lasso_regression/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/safeds/ml/regression/_lasso_regression/test_fit.py b/tests/safeds/ml/regression/_lasso_regression/test_fit.py deleted file mode 100644 index 24e3524d1..000000000 --- a/tests/safeds/ml/regression/_lasso_regression/test_fit.py +++ /dev/null @@ -1,21 +0,0 @@ -import pytest -from safeds.data.tabular.containers import Table, TaggedTable -from safeds.exceptions import LearningError -from safeds.ml.regression import LassoRegression -from tests.fixtures import resolve_resource_path - - -def test_lasso_regression_fit() -> None: - table = Table.from_csv(resolve_resource_path("test_lasso_regression.csv")) - tagged_table = TaggedTable(table, "T") - lasso_regression = LassoRegression() - lasso_regression.fit(tagged_table) - assert True # This asserts that the fit method succeeds - - -def test_lasso_regression_fit_invalid() -> None: - table = Table.from_csv(resolve_resource_path("test_lasso_regression_invalid.csv")) - tagged_table = TaggedTable(table, "T") - lasso_regression = LassoRegression() - with pytest.raises(LearningError): - lasso_regression.fit(tagged_table) diff --git a/tests/safeds/ml/regression/_lasso_regression/test_predict.py b/tests/safeds/ml/regression/_lasso_regression/test_predict.py deleted file mode 100644 index f7307fe78..000000000 --- a/tests/safeds/ml/regression/_lasso_regression/test_predict.py +++ /dev/null @@ -1,35 +0,0 @@ -import pytest -from safeds.data.tabular.containers import Table, TaggedTable -from safeds.exceptions import PredictionError -from safeds.ml.regression import LassoRegression -from tests.fixtures import resolve_resource_path - - -def test_lasso_regression_predict() -> None: - table = Table.from_csv(resolve_resource_path("test_lasso_regression.csv")) - tagged_table = TaggedTable(table, "T") - lasso_regression = LassoRegression() - lasso_regression.fit(tagged_table) - lasso_regression.predict(tagged_table.features) - assert True # This asserts that the predict method succeeds - - -def test_lasso_regression_predict_not_fitted() -> None: - table = Table.from_csv(resolve_resource_path("test_lasso_regression.csv")) - tagged_table = TaggedTable(table, "T") - lasso_regression = LassoRegression() - with pytest.raises(PredictionError): - lasso_regression.predict(tagged_table.features) - - -def test_lasso_regression_predict_invalid() -> None: - table = Table.from_csv(resolve_resource_path("test_lasso_regression.csv")) - invalid_table = Table.from_csv( - resolve_resource_path("test_lasso_regression_invalid.csv") - ) - tagged_table = TaggedTable(table, "T") - invalid_tagged_table = TaggedTable(invalid_table, "T") - lasso_regression = LassoRegression() - lasso_regression.fit(tagged_table) - with pytest.raises(PredictionError): - lasso_regression.predict(invalid_tagged_table.features) diff --git a/tests/safeds/ml/regression/_linear_regression/__init__.py b/tests/safeds/ml/regression/_linear_regression/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/safeds/ml/regression/_linear_regression/test_fit.py b/tests/safeds/ml/regression/_linear_regression/test_fit.py deleted file mode 100644 index eb1ef204b..000000000 --- a/tests/safeds/ml/regression/_linear_regression/test_fit.py +++ /dev/null @@ -1,21 +0,0 @@ -import pytest -from safeds.data.tabular.containers import Table, TaggedTable -from safeds.exceptions import LearningError -from safeds.ml.regression import LinearRegression -from tests.fixtures import resolve_resource_path - - -def test_linear_regression_fit() -> None: - table = Table.from_csv(resolve_resource_path("test_linear_regression.csv")) - tagged_table = TaggedTable(table, "T") - linear_regression = LinearRegression() - linear_regression.fit(tagged_table) - assert True # This asserts that the fit method succeeds - - -def test_linear_regression_fit_invalid() -> None: - table = Table.from_csv(resolve_resource_path("test_linear_regression_invalid.csv")) - tagged_table = TaggedTable(table, "T") - linear_regression = LinearRegression() - with pytest.raises(LearningError): - linear_regression.fit(tagged_table) diff --git a/tests/safeds/ml/regression/_linear_regression/test_predict.py b/tests/safeds/ml/regression/_linear_regression/test_predict.py deleted file mode 100644 index 8dcb8ec2c..000000000 --- a/tests/safeds/ml/regression/_linear_regression/test_predict.py +++ /dev/null @@ -1,35 +0,0 @@ -import pytest -from safeds.data.tabular.containers import Table, TaggedTable -from safeds.exceptions import PredictionError -from safeds.ml.regression import LinearRegression -from tests.fixtures import resolve_resource_path - - -def test_linear_regression_predict() -> None: - table = Table.from_csv(resolve_resource_path("test_linear_regression.csv")) - tagged_table = TaggedTable(table, "T") - linear_regression = LinearRegression() - linear_regression.fit(tagged_table) - linear_regression.predict(tagged_table.features) - assert True # This asserts that the predict method succeeds - - -def test_linear_regression_predict_not_fitted() -> None: - table = Table.from_csv(resolve_resource_path("test_linear_regression.csv")) - tagged_table = TaggedTable(table, "T") - linear_regression = LinearRegression() - with pytest.raises(PredictionError): - linear_regression.predict(tagged_table.features) - - -def test_linear_regression_predict_invalid() -> None: - table = Table.from_csv(resolve_resource_path("test_linear_regression.csv")) - invalid_table = Table.from_csv( - resolve_resource_path("test_linear_regression_invalid.csv") - ) - tagged_table = TaggedTable(table, "T") - invalid_tagged_table = TaggedTable(invalid_table, "T") - linear_regression = LinearRegression() - linear_regression.fit(tagged_table) - with pytest.raises(PredictionError): - linear_regression.predict(invalid_tagged_table.features) diff --git a/tests/safeds/ml/regression/_random_forest/__init__.py b/tests/safeds/ml/regression/_random_forest/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/safeds/ml/regression/_random_forest/test_fit.py b/tests/safeds/ml/regression/_random_forest/test_fit.py deleted file mode 100644 index 551691f5d..000000000 --- a/tests/safeds/ml/regression/_random_forest/test_fit.py +++ /dev/null @@ -1,21 +0,0 @@ -import pytest -from safeds.data.tabular.containers import Table, TaggedTable -from safeds.exceptions import LearningError -from safeds.ml.regression import RandomForest as RandomForestRegressor -from tests.fixtures import resolve_resource_path - - -def test_random_forest_fit() -> None: - table = Table.from_csv(resolve_resource_path("test_random_forest.csv")) - tagged_table = TaggedTable(table, "T") - random_forest = RandomForestRegressor() - random_forest.fit(tagged_table) - assert True # This asserts that the fit method succeeds - - -def test_random_forest_fit_invalid() -> None: - table = Table.from_csv(resolve_resource_path("test_random_forest_invalid.csv")) - tagged_table = TaggedTable(table, "T") - random_forest = RandomForestRegressor() - with pytest.raises(LearningError): - random_forest.fit(tagged_table) diff --git a/tests/safeds/ml/regression/_random_forest/test_predict.py b/tests/safeds/ml/regression/_random_forest/test_predict.py deleted file mode 100644 index 34b35169c..000000000 --- a/tests/safeds/ml/regression/_random_forest/test_predict.py +++ /dev/null @@ -1,35 +0,0 @@ -import pytest -from safeds.data.tabular.containers import Table, TaggedTable -from safeds.exceptions import PredictionError -from safeds.ml.regression import RandomForest as RandomForestRegressor -from tests.fixtures import resolve_resource_path - - -def test_random_forest_predict() -> None: - table = Table.from_csv(resolve_resource_path("test_random_forest.csv")) - tagged_table = TaggedTable(table, "T") - random_forest = RandomForestRegressor() - random_forest.fit(tagged_table) - random_forest.predict(tagged_table.features) - assert True # This asserts that the predict method succeeds - - -def test_random_forest_predict_not_fitted() -> None: - table = Table.from_csv(resolve_resource_path("test_random_forest.csv")) - tagged_table = TaggedTable(table, "T") - random_forest = RandomForestRegressor() - with pytest.raises(PredictionError): - random_forest.predict(tagged_table.features) - - -def test_random_forest_predict_invalid() -> None: - table = Table.from_csv(resolve_resource_path("test_random_forest.csv")) - invalid_table = Table.from_csv( - resolve_resource_path("test_random_forest_invalid.csv") - ) - tagged_table = TaggedTable(table, "T") - invalid_tagged_table = TaggedTable(invalid_table, "T") - random_forest = RandomForestRegressor() - random_forest.fit(tagged_table) - with pytest.raises(PredictionError): - random_forest.predict(invalid_tagged_table.features) diff --git a/tests/safeds/ml/regression/_regressor/__init__.py b/tests/safeds/ml/regression/_regressor/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/safeds/ml/regression/_regressor/_dummy_regressor.py b/tests/safeds/ml/regression/_regressor/_dummy_regressor.py deleted file mode 100644 index 866a6ab6c..000000000 --- a/tests/safeds/ml/regression/_regressor/_dummy_regressor.py +++ /dev/null @@ -1,26 +0,0 @@ -from safeds.data.tabular.containers import Table, TaggedTable -from safeds.ml.regression import Regressor - - -class DummyRegressor(Regressor): - """ - Dummy regressor to test metrics. - - Metrics methods expect a `TaggedTable` as input with two columns: - - - `predicted`: The predicted targets. - - `expected`: The correct targets. - - `target_name` must be set to `"expected"`. - """ - - def fit(self, training_set: TaggedTable) -> None: - pass - - def predict(self, dataset: Table) -> TaggedTable: - # Needed until https://github.com/Safe-DS/Stdlib/issues/75 is fixed - predicted = dataset.get_column("predicted") - feature = predicted.rename("feature") - dataset = Table.from_columns([feature, predicted]) - - return TaggedTable(dataset, target_name="predicted") diff --git a/tests/safeds/ml/regression/_regressor/test_check_metrics_preconditions.py b/tests/safeds/ml/regression/_regressor/test_check_metrics_preconditions.py deleted file mode 100644 index d12ac6da6..000000000 --- a/tests/safeds/ml/regression/_regressor/test_check_metrics_preconditions.py +++ /dev/null @@ -1,30 +0,0 @@ -import pandas as pd -import pytest -from safeds.data.tabular.containers import Column -from safeds.exceptions import ColumnLengthMismatchError - -# noinspection PyProtectedMember -from safeds.ml.regression._regressor import _check_metrics_preconditions - - -@pytest.mark.parametrize( - "actual, expected, error", - [ - (["A", "B"], [1, 2], TypeError), - ([1, 2], ["A", "B"], TypeError), - ([1, 2, 3], [1, 2], ColumnLengthMismatchError), - ], -) -def test_check_metrics_preconditions( - actual: list[str | int], expected: list[str | int], error: type[Exception] -) -> None: - actual_column = Column( - pd.Series(actual), - "actual", - ) - expected_column = Column( - pd.Series(expected), - "expected", - ) - with pytest.raises(error): - _check_metrics_preconditions(actual_column, expected_column) diff --git a/tests/safeds/ml/regression/_regressor/test_mean_absolute_error.py b/tests/safeds/ml/regression/_regressor/test_mean_absolute_error.py deleted file mode 100644 index adb752264..000000000 --- a/tests/safeds/ml/regression/_regressor/test_mean_absolute_error.py +++ /dev/null @@ -1,26 +0,0 @@ -import pytest -from safeds.data.tabular.containers import Column, Table, TaggedTable - -from ._dummy_regressor import DummyRegressor - - -@pytest.mark.parametrize( - "predicted, expected, result", - [ - ([1, 2], [1, 2], 0), - ([0, 0], [1, 1], 1), - ([1, 1, 1], [2, 2, 11], 4), - ([0, 0, 0], [10, 2, 18], 10), - ([0.5, 0.5], [1.5, 1.5], 1), - ], -) -def test_mean_absolute_error_valid( - predicted: list[float], expected: list[float], result: float -) -> None: - predicted_column = Column(predicted, "predicted") - expected_column = Column(expected, "expected") - table = TaggedTable( - Table.from_columns([predicted_column, expected_column]), target_name="expected" - ) - - assert DummyRegressor().mean_absolute_error(table) == result diff --git a/tests/safeds/ml/regression/_regressor/test_mean_squared_error.py b/tests/safeds/ml/regression/_regressor/test_mean_squared_error.py deleted file mode 100644 index 27c85e2de..000000000 --- a/tests/safeds/ml/regression/_regressor/test_mean_squared_error.py +++ /dev/null @@ -1,20 +0,0 @@ -import pytest -from safeds.data.tabular.containers import Column, Table, TaggedTable - -from ._dummy_regressor import DummyRegressor - - -@pytest.mark.parametrize( - "predicted, expected, result", - [([1, 2], [1, 2], 0), ([0, 0], [1, 1], 1), ([1, 1, 1], [2, 2, 11], 34)], -) -def test_mean_squared_error_valid( - predicted: list[float], expected: list[float], result: float -) -> None: - predicted_column = Column(predicted, "predicted") - expected_column = Column(expected, "expected") - table = TaggedTable( - Table.from_columns([predicted_column, expected_column]), target_name="expected" - ) - - assert DummyRegressor().mean_squared_error(table) == result diff --git a/tests/safeds/ml/regression/_ridge_regression/__init__.py b/tests/safeds/ml/regression/_ridge_regression/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/safeds/ml/regression/_ridge_regression/test_fit.py b/tests/safeds/ml/regression/_ridge_regression/test_fit.py deleted file mode 100644 index aa0f7d7bd..000000000 --- a/tests/safeds/ml/regression/_ridge_regression/test_fit.py +++ /dev/null @@ -1,21 +0,0 @@ -import pytest -from safeds.data.tabular.containers import Table, TaggedTable -from safeds.exceptions import LearningError -from safeds.ml.regression import RidgeRegression -from tests.fixtures import resolve_resource_path - - -def test_ridge_regression_fit() -> None: - table = Table.from_csv(resolve_resource_path("test_ridge_regression.csv")) - tagged_table = TaggedTable(table, "T") - ridge_regression = RidgeRegression() - ridge_regression.fit(tagged_table) - assert True # This asserts that the fit method succeeds - - -def test_ridge_regression_fit_invalid() -> None: - table = Table.from_csv(resolve_resource_path("test_ridge_regression_invalid.csv")) - tagged_table = TaggedTable(table, "T") - ridge_regression = RidgeRegression() - with pytest.raises(LearningError): - ridge_regression.fit(tagged_table) diff --git a/tests/safeds/ml/regression/_ridge_regression/test_predict.py b/tests/safeds/ml/regression/_ridge_regression/test_predict.py deleted file mode 100644 index 26cf898d2..000000000 --- a/tests/safeds/ml/regression/_ridge_regression/test_predict.py +++ /dev/null @@ -1,35 +0,0 @@ -import pytest -from safeds.data.tabular.containers import Table, TaggedTable -from safeds.exceptions import PredictionError -from safeds.ml.regression import RidgeRegression -from tests.fixtures import resolve_resource_path - - -def test_ridge_regression_predict() -> None: - table = Table.from_csv(resolve_resource_path("test_ridge_regression.csv")) - tagged_table = TaggedTable(table, "T") - ridge_regression = RidgeRegression() - ridge_regression.fit(tagged_table) - ridge_regression.predict(tagged_table.features) - assert True # This asserts that the predict method succeeds - - -def test_ridge_regression_predict_not_fitted() -> None: - table = Table.from_csv(resolve_resource_path("test_ridge_regression.csv")) - tagged_table = TaggedTable(table, "T") - ridge_regression = RidgeRegression() - with pytest.raises(PredictionError): - ridge_regression.predict(tagged_table.features) - - -def test_ridge_regression_predict_invalid() -> None: - table = Table.from_csv(resolve_resource_path("test_ridge_regression.csv")) - invalid_table = Table.from_csv( - resolve_resource_path("test_ridge_regression_invalid.csv") - ) - tagged_table = TaggedTable(table, "T") - invalid_tagged_table = TaggedTable(invalid_table, "T") - ridge_regression = RidgeRegression() - ridge_regression.fit(tagged_table) - with pytest.raises(PredictionError): - ridge_regression.predict(invalid_tagged_table.features) diff --git a/tests/safeds/ml/regression/metrics/__init__.py b/tests/safeds/ml/regression/metrics/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/safeds/ml/regression/test_ada_boost.py b/tests/safeds/ml/regression/test_ada_boost.py new file mode 100644 index 000000000..d290f49c0 --- /dev/null +++ b/tests/safeds/ml/regression/test_ada_boost.py @@ -0,0 +1,58 @@ +import pytest +from safeds.data.tabular.containers import Table, TaggedTable +from safeds.exceptions import LearningError, PredictionError +from safeds.ml.regression import AdaBoost, Regressor +from tests.fixtures import resolve_resource_path + + +@pytest.fixture() +def regressor() -> Regressor: + return AdaBoost() + + +@pytest.fixture() +def valid_data() -> TaggedTable: + table = Table.from_csv(resolve_resource_path("test_ada_boost.csv")) + return TaggedTable(table, "T") + + +@pytest.fixture() +def invalid_data() -> TaggedTable: + table = Table.from_csv(resolve_resource_path("test_ada_boost_invalid.csv")) + return TaggedTable(table, "T") + + +class TestFit: + def test_should_succeed_on_valid_data( + self, regressor: Regressor, valid_data: TaggedTable + ) -> None: + regressor.fit(valid_data) + assert True # This asserts that the fit method succeeds + + def test_should_raise_on_invalid_data( + self, regressor: Regressor, invalid_data: TaggedTable + ) -> None: + with pytest.raises(LearningError): + regressor.fit(invalid_data) + + +class TestPredict: + def test_should_succeed_on_valid_data( + self, regressor: Regressor, valid_data: TaggedTable + ) -> None: + regressor.fit(valid_data) + regressor.predict(valid_data.features) + assert True # This asserts that the predict method succeeds + + def test_should_raise_when_not_fitted( + self, regressor: Regressor, valid_data: TaggedTable + ) -> None: + with pytest.raises(PredictionError): + regressor.predict(valid_data.features) + + def test_should_raise_on_invalid_data( + self, regressor: Regressor, valid_data: TaggedTable, invalid_data: TaggedTable + ) -> None: + regressor.fit(valid_data) + with pytest.raises(PredictionError): + regressor.predict(invalid_data.features) diff --git a/tests/safeds/ml/regression/test_decision_tree.py b/tests/safeds/ml/regression/test_decision_tree.py new file mode 100644 index 000000000..6db937abe --- /dev/null +++ b/tests/safeds/ml/regression/test_decision_tree.py @@ -0,0 +1,58 @@ +import pytest +from safeds.data.tabular.containers import Table, TaggedTable +from safeds.exceptions import LearningError, PredictionError +from safeds.ml.regression import DecisionTree, Regressor +from tests.fixtures import resolve_resource_path + + +@pytest.fixture() +def regressor() -> Regressor: + return DecisionTree() + + +@pytest.fixture() +def valid_data() -> TaggedTable: + table = Table.from_csv(resolve_resource_path("test_decision_tree.csv")) + return TaggedTable(table, "T") + + +@pytest.fixture() +def invalid_data() -> TaggedTable: + table = Table.from_csv(resolve_resource_path("test_decision_tree_invalid.csv")) + return TaggedTable(table, "T") + + +class TestFit: + def test_should_succeed_on_valid_data( + self, regressor: Regressor, valid_data: TaggedTable + ) -> None: + regressor.fit(valid_data) + assert True # This asserts that the fit method succeeds + + def test_should_raise_on_invalid_data( + self, regressor: Regressor, invalid_data: TaggedTable + ) -> None: + with pytest.raises(LearningError): + regressor.fit(invalid_data) + + +class TestPredict: + def test_should_succeed_on_valid_data( + self, regressor: Regressor, valid_data: TaggedTable + ) -> None: + regressor.fit(valid_data) + regressor.predict(valid_data.features) + assert True # This asserts that the predict method succeeds + + def test_should_raise_when_not_fitted( + self, regressor: Regressor, valid_data: TaggedTable + ) -> None: + with pytest.raises(PredictionError): + regressor.predict(valid_data.features) + + def test_should_raise_on_invalid_data( + self, regressor: Regressor, valid_data: TaggedTable, invalid_data: TaggedTable + ) -> None: + regressor.fit(valid_data) + with pytest.raises(PredictionError): + regressor.predict(invalid_data.features) diff --git a/tests/safeds/ml/regression/test_elastic_net.py b/tests/safeds/ml/regression/test_elastic_net.py new file mode 100644 index 000000000..06e443372 --- /dev/null +++ b/tests/safeds/ml/regression/test_elastic_net.py @@ -0,0 +1,60 @@ +import pytest +from safeds.data.tabular.containers import Table, TaggedTable +from safeds.exceptions import LearningError, PredictionError +from safeds.ml.regression import ElasticNetRegression, Regressor +from tests.fixtures import resolve_resource_path + + +@pytest.fixture() +def regressor() -> Regressor: + return ElasticNetRegression() + + +@pytest.fixture() +def valid_data() -> TaggedTable: + table = Table.from_csv(resolve_resource_path("test_elastic_net_regression.csv")) + return TaggedTable(table, "T") + + +@pytest.fixture() +def invalid_data() -> TaggedTable: + table = Table.from_csv( + resolve_resource_path("test_elastic_net_regression_invalid.csv") + ) + return TaggedTable(table, "T") + + +class TestFit: + def test_should_succeed_on_valid_data( + self, regressor: Regressor, valid_data: TaggedTable + ) -> None: + regressor.fit(valid_data) + assert True # This asserts that the fit method succeeds + + def test_should_raise_on_invalid_data( + self, regressor: Regressor, invalid_data: TaggedTable + ) -> None: + with pytest.raises(LearningError): + regressor.fit(invalid_data) + + +class TestPredict: + def test_should_succeed_on_valid_data( + self, regressor: Regressor, valid_data: TaggedTable + ) -> None: + regressor.fit(valid_data) + regressor.predict(valid_data.features) + assert True # This asserts that the predict method succeeds + + def test_should_raise_when_not_fitted( + self, regressor: Regressor, valid_data: TaggedTable + ) -> None: + with pytest.raises(PredictionError): + regressor.predict(valid_data.features) + + def test_should_raise_on_invalid_data( + self, regressor: Regressor, valid_data: TaggedTable, invalid_data: TaggedTable + ) -> None: + regressor.fit(valid_data) + with pytest.raises(PredictionError): + regressor.predict(invalid_data.features) diff --git a/tests/safeds/ml/regression/test_gradient_boosting.py b/tests/safeds/ml/regression/test_gradient_boosting.py new file mode 100644 index 000000000..023dd76f4 --- /dev/null +++ b/tests/safeds/ml/regression/test_gradient_boosting.py @@ -0,0 +1,62 @@ +import pytest +from safeds.data.tabular.containers import Table, TaggedTable +from safeds.exceptions import LearningError, PredictionError +from safeds.ml.regression import GradientBoosting, Regressor +from tests.fixtures import resolve_resource_path + + +@pytest.fixture() +def regressor() -> Regressor: + return GradientBoosting() + + +@pytest.fixture() +def valid_data() -> TaggedTable: + table = Table.from_csv( + resolve_resource_path("test_gradient_boosting_regression.csv") + ) + return TaggedTable(table, "T") + + +@pytest.fixture() +def invalid_data() -> TaggedTable: + table = Table.from_csv( + resolve_resource_path("test_gradient_boosting_regression_invalid.csv") + ) + return TaggedTable(table, "T") + + +class TestFit: + def test_should_succeed_on_valid_data( + self, regressor: Regressor, valid_data: TaggedTable + ) -> None: + regressor.fit(valid_data) + assert True # This asserts that the fit method succeeds + + def test_should_raise_on_invalid_data( + self, regressor: Regressor, invalid_data: TaggedTable + ) -> None: + with pytest.raises(LearningError): + regressor.fit(invalid_data) + + +class TestPredict: + def test_should_succeed_on_valid_data( + self, regressor: Regressor, valid_data: TaggedTable + ) -> None: + regressor.fit(valid_data) + regressor.predict(valid_data.features) + assert True # This asserts that the predict method succeeds + + def test_should_raise_when_not_fitted( + self, regressor: Regressor, valid_data: TaggedTable + ) -> None: + with pytest.raises(PredictionError): + regressor.predict(valid_data.features) + + def test_should_raise_on_invalid_data( + self, regressor: Regressor, valid_data: TaggedTable, invalid_data: TaggedTable + ) -> None: + regressor.fit(valid_data) + with pytest.raises(PredictionError): + regressor.predict(invalid_data.features) diff --git a/tests/safeds/ml/regression/test_k_nearest_neighbors.py b/tests/safeds/ml/regression/test_k_nearest_neighbors.py new file mode 100644 index 000000000..0ad18d54a --- /dev/null +++ b/tests/safeds/ml/regression/test_k_nearest_neighbors.py @@ -0,0 +1,60 @@ +import pytest +from safeds.data.tabular.containers import Table, TaggedTable +from safeds.exceptions import LearningError, PredictionError +from safeds.ml.regression import KNearestNeighbors, Regressor +from tests.fixtures import resolve_resource_path + + +@pytest.fixture() +def regressor() -> Regressor: + return KNearestNeighbors(2) + + +@pytest.fixture() +def valid_data() -> TaggedTable: + table = Table.from_csv(resolve_resource_path("test_k_nearest_neighbors.csv")) + return TaggedTable(table, "T") + + +@pytest.fixture() +def invalid_data() -> TaggedTable: + table = Table.from_csv( + resolve_resource_path("test_k_nearest_neighbors_invalid.csv") + ) + return TaggedTable(table, "T") + + +class TestFit: + def test_should_succeed_on_valid_data( + self, regressor: Regressor, valid_data: TaggedTable + ) -> None: + regressor.fit(valid_data) + assert True # This asserts that the fit method succeeds + + def test_should_raise_on_invalid_data( + self, regressor: Regressor, invalid_data: TaggedTable + ) -> None: + with pytest.raises(LearningError): + regressor.fit(invalid_data) + + +class TestPredict: + def test_should_succeed_on_valid_data( + self, regressor: Regressor, valid_data: TaggedTable + ) -> None: + regressor.fit(valid_data) + regressor.predict(valid_data.features) + assert True # This asserts that the predict method succeeds + + def test_should_raise_when_not_fitted( + self, regressor: Regressor, valid_data: TaggedTable + ) -> None: + with pytest.raises(PredictionError): + regressor.predict(valid_data.features) + + def test_should_raise_on_invalid_data( + self, regressor: Regressor, valid_data: TaggedTable, invalid_data: TaggedTable + ) -> None: + regressor.fit(valid_data) + with pytest.raises(PredictionError): + regressor.predict(invalid_data.features) diff --git a/tests/safeds/ml/regression/test_lasso_regression.py b/tests/safeds/ml/regression/test_lasso_regression.py new file mode 100644 index 000000000..362871a31 --- /dev/null +++ b/tests/safeds/ml/regression/test_lasso_regression.py @@ -0,0 +1,58 @@ +import pytest +from safeds.data.tabular.containers import Table, TaggedTable +from safeds.exceptions import LearningError, PredictionError +from safeds.ml.regression import LassoRegression, Regressor +from tests.fixtures import resolve_resource_path + + +@pytest.fixture() +def regressor() -> Regressor: + return LassoRegression() + + +@pytest.fixture() +def valid_data() -> TaggedTable: + table = Table.from_csv(resolve_resource_path("test_lasso_regression.csv")) + return TaggedTable(table, "T") + + +@pytest.fixture() +def invalid_data() -> TaggedTable: + table = Table.from_csv(resolve_resource_path("test_lasso_regression_invalid.csv")) + return TaggedTable(table, "T") + + +class TestFit: + def test_should_succeed_on_valid_data( + self, regressor: Regressor, valid_data: TaggedTable + ) -> None: + regressor.fit(valid_data) + assert True # This asserts that the fit method succeeds + + def test_should_raise_on_invalid_data( + self, regressor: Regressor, invalid_data: TaggedTable + ) -> None: + with pytest.raises(LearningError): + regressor.fit(invalid_data) + + +class TestPredict: + def test_should_succeed_on_valid_data( + self, regressor: Regressor, valid_data: TaggedTable + ) -> None: + regressor.fit(valid_data) + regressor.predict(valid_data.features) + assert True # This asserts that the predict method succeeds + + def test_should_raise_when_not_fitted( + self, regressor: Regressor, valid_data: TaggedTable + ) -> None: + with pytest.raises(PredictionError): + regressor.predict(valid_data.features) + + def test_should_raise_on_invalid_data( + self, regressor: Regressor, valid_data: TaggedTable, invalid_data: TaggedTable + ) -> None: + regressor.fit(valid_data) + with pytest.raises(PredictionError): + regressor.predict(invalid_data.features) diff --git a/tests/safeds/ml/regression/test_linear_regression.py b/tests/safeds/ml/regression/test_linear_regression.py new file mode 100644 index 000000000..fbabe70ec --- /dev/null +++ b/tests/safeds/ml/regression/test_linear_regression.py @@ -0,0 +1,58 @@ +import pytest +from safeds.data.tabular.containers import Table, TaggedTable +from safeds.exceptions import LearningError, PredictionError +from safeds.ml.regression import LinearRegression, Regressor +from tests.fixtures import resolve_resource_path + + +@pytest.fixture() +def regressor() -> Regressor: + return LinearRegression() + + +@pytest.fixture() +def valid_data() -> TaggedTable: + table = Table.from_csv(resolve_resource_path("test_linear_regression.csv")) + return TaggedTable(table, "T") + + +@pytest.fixture() +def invalid_data() -> TaggedTable: + table = Table.from_csv(resolve_resource_path("test_linear_regression_invalid.csv")) + return TaggedTable(table, "T") + + +class TestFit: + def test_should_succeed_on_valid_data( + self, regressor: Regressor, valid_data: TaggedTable + ) -> None: + regressor.fit(valid_data) + assert True # This asserts that the fit method succeeds + + def test_should_raise_on_invalid_data( + self, regressor: Regressor, invalid_data: TaggedTable + ) -> None: + with pytest.raises(LearningError): + regressor.fit(invalid_data) + + +class TestPredict: + def test_should_succeed_on_valid_data( + self, regressor: Regressor, valid_data: TaggedTable + ) -> None: + regressor.fit(valid_data) + regressor.predict(valid_data.features) + assert True # This asserts that the predict method succeeds + + def test_should_raise_when_not_fitted( + self, regressor: Regressor, valid_data: TaggedTable + ) -> None: + with pytest.raises(PredictionError): + regressor.predict(valid_data.features) + + def test_should_raise_on_invalid_data( + self, regressor: Regressor, valid_data: TaggedTable, invalid_data: TaggedTable + ) -> None: + regressor.fit(valid_data) + with pytest.raises(PredictionError): + regressor.predict(invalid_data.features) diff --git a/tests/safeds/ml/regression/test_random_forest.py b/tests/safeds/ml/regression/test_random_forest.py new file mode 100644 index 000000000..87a30bbce --- /dev/null +++ b/tests/safeds/ml/regression/test_random_forest.py @@ -0,0 +1,58 @@ +import pytest +from safeds.data.tabular.containers import Table, TaggedTable +from safeds.exceptions import LearningError, PredictionError +from safeds.ml.regression import RandomForest, Regressor +from tests.fixtures import resolve_resource_path + + +@pytest.fixture() +def regressor() -> Regressor: + return RandomForest() + + +@pytest.fixture() +def valid_data() -> TaggedTable: + table = Table.from_csv(resolve_resource_path("test_random_forest.csv")) + return TaggedTable(table, "T") + + +@pytest.fixture() +def invalid_data() -> TaggedTable: + table = Table.from_csv(resolve_resource_path("test_random_forest_invalid.csv")) + return TaggedTable(table, "T") + + +class TestFit: + def test_should_succeed_on_valid_data( + self, regressor: Regressor, valid_data: TaggedTable + ) -> None: + regressor.fit(valid_data) + assert True # This asserts that the fit method succeeds + + def test_should_raise_on_invalid_data( + self, regressor: Regressor, invalid_data: TaggedTable + ) -> None: + with pytest.raises(LearningError): + regressor.fit(invalid_data) + + +class TestPredict: + def test_should_succeed_on_valid_data( + self, regressor: Regressor, valid_data: TaggedTable + ) -> None: + regressor.fit(valid_data) + regressor.predict(valid_data.features) + assert True # This asserts that the predict method succeeds + + def test_should_raise_when_not_fitted( + self, regressor: Regressor, valid_data: TaggedTable + ) -> None: + with pytest.raises(PredictionError): + regressor.predict(valid_data.features) + + def test_should_raise_on_invalid_data( + self, regressor: Regressor, valid_data: TaggedTable, invalid_data: TaggedTable + ) -> None: + regressor.fit(valid_data) + with pytest.raises(PredictionError): + regressor.predict(invalid_data.features) diff --git a/tests/safeds/ml/regression/test_regressor.py b/tests/safeds/ml/regression/test_regressor.py new file mode 100644 index 000000000..fcba2aba4 --- /dev/null +++ b/tests/safeds/ml/regression/test_regressor.py @@ -0,0 +1,98 @@ +import pandas as pd +import pytest +from safeds.data.tabular.containers import Column, Table, TaggedTable +from safeds.exceptions import ColumnLengthMismatchError +from safeds.ml.regression import Regressor + +# noinspection PyProtectedMember +from safeds.ml.regression._regressor import _check_metrics_preconditions + + +class DummyRegressor(Regressor): + """ + Dummy regressor to test metrics. + + Metrics methods expect a `TaggedTable` as input with two columns: + + - `predicted`: The predicted targets. + - `expected`: The correct targets. + + `target_name` must be set to `"expected"`. + """ + + def fit(self, training_set: TaggedTable) -> None: + pass + + def predict(self, dataset: Table) -> TaggedTable: + # Needed until https://github.com/Safe-DS/Stdlib/issues/75 is fixed + predicted = dataset.get_column("predicted") + feature = predicted.rename("feature") + dataset = Table.from_columns([feature, predicted]) + + return TaggedTable(dataset, target_name="predicted") + + +class TestMeanAbsoluteError: + @pytest.mark.parametrize( + "predicted, expected, result", + [ + ([1, 2], [1, 2], 0), + ([0, 0], [1, 1], 1), + ([1, 1, 1], [2, 2, 11], 4), + ([0, 0, 0], [10, 2, 18], 10), + ([0.5, 0.5], [1.5, 1.5], 1), + ], + ) + def test_valid_data( + self, predicted: list[float], expected: list[float], result: float + ) -> None: + predicted_column = Column(predicted, "predicted") + expected_column = Column(expected, "expected") + table = TaggedTable( + Table.from_columns([predicted_column, expected_column]), + target_name="expected", + ) + + assert DummyRegressor().mean_absolute_error(table) == result + + +class TestMeanSquaredError: + @pytest.mark.parametrize( + "predicted, expected, result", + [([1, 2], [1, 2], 0), ([0, 0], [1, 1], 1), ([1, 1, 1], [2, 2, 11], 34)], + ) + def test_valid_data( + self, predicted: list[float], expected: list[float], result: float + ) -> None: + predicted_column = Column(predicted, "predicted") + expected_column = Column(expected, "expected") + table = TaggedTable( + Table.from_columns([predicted_column, expected_column]), + target_name="expected", + ) + + assert DummyRegressor().mean_squared_error(table) == result + + +class TestCheckMetricsPreconditions: + @pytest.mark.parametrize( + "actual, expected, error", + [ + (["A", "B"], [1, 2], TypeError), + ([1, 2], ["A", "B"], TypeError), + ([1, 2, 3], [1, 2], ColumnLengthMismatchError), + ], + ) + def test_should_raise_if_validation_fails( + self, actual: list[str | int], expected: list[str | int], error: type[Exception] + ) -> None: + actual_column = Column( + pd.Series(actual), + "actual", + ) + expected_column = Column( + pd.Series(expected), + "expected", + ) + with pytest.raises(error): + _check_metrics_preconditions(actual_column, expected_column) diff --git a/tests/safeds/ml/regression/test_ridge_regression.py b/tests/safeds/ml/regression/test_ridge_regression.py new file mode 100644 index 000000000..6f201e9e9 --- /dev/null +++ b/tests/safeds/ml/regression/test_ridge_regression.py @@ -0,0 +1,58 @@ +import pytest +from safeds.data.tabular.containers import Table, TaggedTable +from safeds.exceptions import LearningError, PredictionError +from safeds.ml.regression import Regressor, RidgeRegression +from tests.fixtures import resolve_resource_path + + +@pytest.fixture() +def regressor() -> Regressor: + return RidgeRegression() + + +@pytest.fixture() +def valid_data() -> TaggedTable: + table = Table.from_csv(resolve_resource_path("test_ridge_regression.csv")) + return TaggedTable(table, "T") + + +@pytest.fixture() +def invalid_data() -> TaggedTable: + table = Table.from_csv(resolve_resource_path("test_ridge_regression_invalid.csv")) + return TaggedTable(table, "T") + + +class TestFit: + def test_should_succeed_on_valid_data( + self, regressor: Regressor, valid_data: TaggedTable + ) -> None: + regressor.fit(valid_data) + assert True # This asserts that the fit method succeeds + + def test_should_raise_on_invalid_data( + self, regressor: Regressor, invalid_data: TaggedTable + ) -> None: + with pytest.raises(LearningError): + regressor.fit(invalid_data) + + +class TestPredict: + def test_should_succeed_on_valid_data( + self, regressor: Regressor, valid_data: TaggedTable + ) -> None: + regressor.fit(valid_data) + regressor.predict(valid_data.features) + assert True # This asserts that the predict method succeeds + + def test_should_raise_when_not_fitted( + self, regressor: Regressor, valid_data: TaggedTable + ) -> None: + with pytest.raises(PredictionError): + regressor.predict(valid_data.features) + + def test_should_raise_on_invalid_data( + self, regressor: Regressor, valid_data: TaggedTable, invalid_data: TaggedTable + ) -> None: + regressor.fit(valid_data) + with pytest.raises(PredictionError): + regressor.predict(invalid_data.features)