From b4a56b5cda47708de7f407638d5d1a7b90a676ce Mon Sep 17 00:00:00 2001 From: Lars Reimann Date: Wed, 29 Mar 2023 10:33:44 +0200 Subject: [PATCH 01/14] refactor: import `Table` only when type checking --- src/safeds/data/tabular/transformation/_table_transformer.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/safeds/data/tabular/transformation/_table_transformer.py b/src/safeds/data/tabular/transformation/_table_transformer.py index b2844de22..3b3248eb1 100644 --- a/src/safeds/data/tabular/transformation/_table_transformer.py +++ b/src/safeds/data/tabular/transformation/_table_transformer.py @@ -1,9 +1,10 @@ from __future__ import annotations from abc import ABC, abstractmethod -from typing import Optional +from typing import Optional, TYPE_CHECKING -from safeds.data.tabular.containers import Table +if TYPE_CHECKING: + from safeds.data.tabular.containers import Table class TableTransformer(ABC): From 803d5822a0135beae9ec38be4859974ee4d6579f Mon Sep 17 00:00:00 2001 From: Lars Reimann Date: Wed, 29 Mar 2023 10:34:35 +0200 Subject: [PATCH 02/14] feat: specify features and targets when creating a `TaggedTable` --- src/safeds/data/tabular/containers/_table.py | 46 ++++++++++++---- .../data/tabular/containers/_tagged_table.py | 55 +++++++++++++------ tests/resources/test_tagged_table.csv | 3 - .../containers/_tagged_table/__init__.py | 0 .../containers/_tagged_table/test_features.py | 11 ---- .../containers/_tagged_table/test_target.py | 9 --- .../tabular/containers/test_tagged_table.py | 55 +++++++++++++++++++ 7 files changed, 128 insertions(+), 51 deletions(-) delete mode 100644 tests/resources/test_tagged_table.csv delete mode 100644 tests/safeds/data/tabular/containers/_tagged_table/__init__.py delete mode 100644 tests/safeds/data/tabular/containers/_tagged_table/test_features.py delete mode 100644 tests/safeds/data/tabular/containers/_tagged_table/test_target.py create mode 100644 tests/safeds/data/tabular/containers/test_tagged_table.py diff --git a/src/safeds/data/tabular/containers/_table.py b/src/safeds/data/tabular/containers/_table.py index 3cec5c269..9ad2e1747 100644 --- a/src/safeds/data/tabular/containers/_table.py +++ b/src/safeds/data/tabular/containers/_table.py @@ -2,9 +2,8 @@ import functools import os.path -import typing from pathlib import Path -from typing import Callable, Optional, Union +from typing import Callable, Optional, Union, Iterable, Any, TYPE_CHECKING import matplotlib.pyplot as plt import numpy as np @@ -12,8 +11,13 @@ import seaborn as sns from IPython.core.display_functions import DisplayHandle, display from pandas import DataFrame, Series -from safeds.data.tabular.containers._column import Column -from safeds.data.tabular.containers._row import Row +from scipy import stats + +if TYPE_CHECKING: + from ._tagged_table import TaggedTable + +from ._column import Column +from ._row import Row from safeds.data.tabular.typing import ColumnType, TableSchema from safeds.exceptions import ( ColumnLengthMismatchError, @@ -26,7 +30,6 @@ SchemaMismatchError, UnknownColumnNameError, ) -from scipy import stats # noinspection PyProtectedMember @@ -188,7 +191,7 @@ def from_rows(rows: list[Row]) -> Table: # Dunder methods # ------------------------------------------------------------------------------------------------------------------ - def __init__(self, data: typing.Iterable, schema: Optional[TableSchema] = None): + def __init__(self, data: Iterable, schema: Optional[TableSchema] = None): self._data: pd.Dataframe = data if isinstance(data, pd.DataFrame) else pd.DataFrame(data) if schema is None: if self.count_columns() == 0: @@ -202,7 +205,7 @@ def __init__(self, data: typing.Iterable, schema: Optional[TableSchema] = None): self._data = self._data.reset_index(drop=True) self._data.columns = list(range(self.count_columns())) - def __eq__(self, other: typing.Any) -> bool: + def __eq__(self, other: Any) -> bool: if not isinstance(other, Table): return NotImplemented if self is other: @@ -782,8 +785,8 @@ def shuffle(self) -> Table: def slice( self, - start: typing.Optional[int] = None, - end: typing.Optional[int] = None, + start: Optional[int] = None, + end: Optional[int] = None, step: int = 1, ) -> Table: """ @@ -825,7 +828,7 @@ def slice( def sort_columns( self, comparator: Callable[[Column, Column], int] = lambda col1, col2: (col1.name > col2.name) - - (col1.name < col2.name), + - (col1.name < col2.name), ) -> Table: """ Sort the columns of a `Table` with the given comparator and return a new `Table`. The original table is not @@ -878,7 +881,7 @@ def sort_rows(self, comparator: Callable[[Row, Row], int]) -> Table: rows.sort(key=functools.cmp_to_key(comparator)) return Table.from_rows(rows) - def split(self, percentage_in_first: float) -> typing.Tuple[Table, Table]: + def split(self, percentage_in_first: float) -> tuple[Table, Table]: """ Split the table into two new tables. @@ -902,7 +905,26 @@ def split(self, percentage_in_first: float) -> typing.Tuple[Table, Table]: self.slice(round(percentage_in_first * self.count_rows())), ) - def transform_column(self, name: str, transformer: Callable[[Row], typing.Any]) -> Table: + def tag_columns(self, target_name: str, feature_names: Optional[list[str]] = None) -> TaggedTable: + """ + Mark the columns of the table as target column or feature columns. The original table is not modified. + + Parameters + ---------- + target_name : str + Name of the target column. + feature_names : Optional[list[str]] + Names of the feature columns. If None, all columns except the target column are used. + + Returns + ------- + tagged_table : TaggedTable + A new tagged table with the given target and feature names. + """ + from ._tagged_table import TaggedTable + return TaggedTable(self._data, target_name, feature_names, self._schema) + + def transform_column(self, name: str, transformer: Callable[[Row], Any]) -> Table: """ Transform provided column by calling provided transformer. diff --git a/src/safeds/data/tabular/containers/_tagged_table.py b/src/safeds/data/tabular/containers/_tagged_table.py index 8eb4521d7..7af43e47e 100644 --- a/src/safeds/data/tabular/containers/_tagged_table.py +++ b/src/safeds/data/tabular/containers/_tagged_table.py @@ -1,7 +1,9 @@ +from typing import Iterable, Optional + from IPython.core.display_functions import DisplayHandle -from ._column import Column -from ._table import Table +from safeds.data.tabular.containers import Table, Column +from safeds.data.tabular.typing import TableSchema class TaggedTable(Table): @@ -10,34 +12,55 @@ class TaggedTable(Table): Parameters ---------- - table : Table - The table used to derive the features and target. + data : Iterable + The data. target_name : str Name of the target column. + feature_names : Optional[list[str]] + Names of the feature columns. If None, all columns except the target column are used. + schema : Optional[TableSchema] + The schema of the table. If not specified, the schema will be inferred from the data. """ - def __init__(self, table: Table, target_name: str): - super().__init__(table._data) + def __init__( + self, + data: Iterable, + target_name: str, + feature_names: Optional[list[str]] = None, + schema: Optional[TableSchema] = None + ): + # Validate input + if feature_names is not None: + if target_name in feature_names: + raise ValueError(f"Column '{target_name}' cannot be both feature and target.") + elif len(feature_names) == 0: + raise ValueError("At least one feature column must be specified.") + + super().__init__(data, schema) + + if feature_names is None: + self._features: Table = self.drop_columns([target_name]) + else: + self._features: Table = self.keep_only_columns(feature_names) - self._y: Column = table.get_column(target_name) - self._X: Table = table.drop_columns([target_name]) + self._target: Column = self.get_column(target_name) @property def features(self) -> Table: - return self._X + return self._features @property def target(self) -> Column: - return self._y + return self._target def __repr__(self) -> str: - tmp = self._X.add_column(self._y) - header_info = "Target Column is '" + self._y.name + "'\n" + tmp = self._features.add_column(self._target) + header_info = "Target Column is '" + self._target.name + "'\n" return header_info + tmp.__repr__() def __str__(self) -> str: - tmp = self._X.add_column(self._y) - header_info = "Target Column is '" + self._y.name + "'\n" + tmp = self._features.add_column(self._target) + header_info = "Target Column is '" + self._target.name + "'\n" return header_info + tmp.__str__() def _ipython_display_(self) -> DisplayHandle: @@ -49,7 +72,7 @@ def _ipython_display_(self) -> DisplayHandle: output : DisplayHandle Output object. """ - tmp = self._X.add_column(self._y) - header_info = "Target Column is '" + self._y.name + "'\n" + tmp = self._features.add_column(self._target) + header_info = "Target Column is '" + self._target.name + "'\n" print(header_info) return tmp._ipython_display_() diff --git a/tests/resources/test_tagged_table.csv b/tests/resources/test_tagged_table.csv deleted file mode 100644 index 5ba8f4fad..000000000 --- a/tests/resources/test_tagged_table.csv +++ /dev/null @@ -1,3 +0,0 @@ -A,B,C,T -1,2,3,0 -4,5,6,1 diff --git a/tests/safeds/data/tabular/containers/_tagged_table/__init__.py b/tests/safeds/data/tabular/containers/_tagged_table/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/safeds/data/tabular/containers/_tagged_table/test_features.py b/tests/safeds/data/tabular/containers/_tagged_table/test_features.py deleted file mode 100644 index 6110227c0..000000000 --- a/tests/safeds/data/tabular/containers/_tagged_table/test_features.py +++ /dev/null @@ -1,11 +0,0 @@ -from safeds.data.tabular.containers import Table, TaggedTable -from tests.fixtures import resolve_resource_path - - -def test_tagged_table_features() -> None: - table = Table.from_csv_file(resolve_resource_path("test_tagged_table.csv")) - tagged_table = TaggedTable(table, "T") - assert "T" not in tagged_table.features._data - assert tagged_table.features.schema.has_column("A") - assert tagged_table.features.schema.has_column("B") - assert tagged_table.features.schema.has_column("C") diff --git a/tests/safeds/data/tabular/containers/_tagged_table/test_target.py b/tests/safeds/data/tabular/containers/_tagged_table/test_target.py deleted file mode 100644 index 9fc6bec26..000000000 --- a/tests/safeds/data/tabular/containers/_tagged_table/test_target.py +++ /dev/null @@ -1,9 +0,0 @@ -from safeds.data.tabular.containers import Table, TaggedTable -from tests.fixtures import resolve_resource_path - - -def test_tagged_table_target() -> None: - table = Table.from_csv_file(resolve_resource_path("test_tagged_table.csv")) - tagged_table = TaggedTable(table, "T") - assert tagged_table.target._data[0] == 0 - assert tagged_table.target._data[1] == 1 diff --git a/tests/safeds/data/tabular/containers/test_tagged_table.py b/tests/safeds/data/tabular/containers/test_tagged_table.py new file mode 100644 index 000000000..dbb513234 --- /dev/null +++ b/tests/safeds/data/tabular/containers/test_tagged_table.py @@ -0,0 +1,55 @@ +import pytest + +from safeds.data.tabular.containers import Table, TaggedTable, Column +from safeds.exceptions import UnknownColumnNameError + + +@pytest.fixture +def table() -> Table: + return Table.from_columns( + [ + Column("A", [1, 4]), + Column("B", [2, 5]), + Column("C", [3, 6]), + Column("T", [0, 1]), + ] + ) + + +@pytest.fixture +def tagged_table(table: Table) -> TaggedTable: + return table.tag_columns(target_name="T") + + +class TestInit: + def test_should_raise_if_a_feature_does_not_exist(self, table: Table) -> None: + with pytest.raises(UnknownColumnNameError): + table.tag_columns(target_name="T", feature_names=["A", "B", "C", "D"]) + + def test_should_raise_if_target_does_not_exist(self, table: Table) -> None: + with pytest.raises(UnknownColumnNameError): + table.tag_columns(target_name="D") + + def test_should_raise_if_features_and_target_overlap(self, table: Table) -> None: + with pytest.raises(ValueError): + table.tag_columns(target_name="A", feature_names=["A", "B", "C"]) + + def test_should_raise_if_features_are_empty(self, table: Table) -> None: + with pytest.raises(ValueError): + table.tag_columns(target_name="A", feature_names=[]) + + +class TestFeatures: + def test_should_return_features(self, tagged_table: TaggedTable) -> None: + assert tagged_table.features == Table.from_columns( + [ + Column("A", [1, 4]), + Column("B", [2, 5]), + Column("C", [3, 6]), + ] + ) + + +class TestTarget: + def test_should_return_target(self, tagged_table: TaggedTable) -> None: + assert tagged_table.target == Column("T", [0, 1]) From 001308618725d07eaaaf0ebb1a9ac4a2c87bab67 Mon Sep 17 00:00:00 2001 From: Lars Reimann Date: Wed, 29 Mar 2023 14:32:02 +0200 Subject: [PATCH 03/14] style: fix linter errors --- src/safeds/data/tabular/containers/_table.py | 11 ++++++----- src/safeds/data/tabular/containers/_tagged_table.py | 8 ++------ tests/safeds/ml/test_util_sklearn.py | 4 ++-- 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/safeds/data/tabular/containers/_table.py b/src/safeds/data/tabular/containers/_table.py index 9ad2e1747..74dcdc653 100644 --- a/src/safeds/data/tabular/containers/_table.py +++ b/src/safeds/data/tabular/containers/_table.py @@ -13,11 +13,6 @@ from pandas import DataFrame, Series from scipy import stats -if TYPE_CHECKING: - from ._tagged_table import TaggedTable - -from ._column import Column -from ._row import Row from safeds.data.tabular.typing import ColumnType, TableSchema from safeds.exceptions import ( ColumnLengthMismatchError, @@ -30,6 +25,11 @@ SchemaMismatchError, UnknownColumnNameError, ) +from ._column import Column +from ._row import Row + +if TYPE_CHECKING: + from ._tagged_table import TaggedTable # noinspection PyProtectedMember @@ -921,6 +921,7 @@ def tag_columns(self, target_name: str, feature_names: Optional[list[str]] = Non tagged_table : TaggedTable A new tagged table with the given target and feature names. """ + # pylint: disable=import-outside-toplevel from ._tagged_table import TaggedTable return TaggedTable(self._data, target_name, feature_names, self._schema) diff --git a/src/safeds/data/tabular/containers/_tagged_table.py b/src/safeds/data/tabular/containers/_tagged_table.py index 7af43e47e..2cb0edc58 100644 --- a/src/safeds/data/tabular/containers/_tagged_table.py +++ b/src/safeds/data/tabular/containers/_tagged_table.py @@ -33,16 +33,12 @@ def __init__( if feature_names is not None: if target_name in feature_names: raise ValueError(f"Column '{target_name}' cannot be both feature and target.") - elif len(feature_names) == 0: + if len(feature_names) == 0: raise ValueError("At least one feature column must be specified.") super().__init__(data, schema) - if feature_names is None: - self._features: Table = self.drop_columns([target_name]) - else: - self._features: Table = self.keep_only_columns(feature_names) - + self._features: Table = self.drop_columns([target_name]) if feature_names is None else self.keep_only_columns(feature_names) self._target: Column = self.get_column(target_name) @property diff --git a/tests/safeds/ml/test_util_sklearn.py b/tests/safeds/ml/test_util_sklearn.py index 88bb03b3c..c9fab0824 100644 --- a/tests/safeds/ml/test_util_sklearn.py +++ b/tests/safeds/ml/test_util_sklearn.py @@ -1,6 +1,6 @@ import warnings -from safeds.data.tabular.containers import Table, TaggedTable +from safeds.data.tabular.containers import Table from safeds.ml.regression import LinearRegression @@ -9,7 +9,7 @@ def test_predict_should_not_warn_about_feature_names() -> None: See https://github.com/Safe-DS/Stdlib/issues/51. """ - training_set = TaggedTable(Table({"a": [1, 2, 3], "b": [2, 4, 6]}), target_name="b") + training_set = Table({"a": [1, 2, 3], "b": [2, 4, 6]}).tag_columns(target_name="b") model = LinearRegression() fitted_model = model.fit(training_set) From 00baf0ab07e5aa66c48eddbb5aa3315798d339d5 Mon Sep 17 00:00:00 2001 From: lars-reimann Date: Wed, 29 Mar 2023 12:38:11 +0000 Subject: [PATCH 04/14] style: apply automated linter fixes --- src/safeds/data/tabular/containers/_table.py | 9 +++++---- src/safeds/data/tabular/containers/_tagged_table.py | 9 +++++---- .../data/tabular/transformation/_table_transformer.py | 2 +- .../safeds/data/tabular/containers/test_tagged_table.py | 3 +-- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/safeds/data/tabular/containers/_table.py b/src/safeds/data/tabular/containers/_table.py index 74dcdc653..0c021e3a7 100644 --- a/src/safeds/data/tabular/containers/_table.py +++ b/src/safeds/data/tabular/containers/_table.py @@ -3,7 +3,7 @@ import functools import os.path from pathlib import Path -from typing import Callable, Optional, Union, Iterable, Any, TYPE_CHECKING +from typing import TYPE_CHECKING, Any, Callable, Iterable, Optional, Union import matplotlib.pyplot as plt import numpy as np @@ -11,8 +11,6 @@ import seaborn as sns from IPython.core.display_functions import DisplayHandle, display from pandas import DataFrame, Series -from scipy import stats - from safeds.data.tabular.typing import ColumnType, TableSchema from safeds.exceptions import ( ColumnLengthMismatchError, @@ -25,6 +23,8 @@ SchemaMismatchError, UnknownColumnNameError, ) +from scipy import stats + from ._column import Column from ._row import Row @@ -828,7 +828,7 @@ def slice( def sort_columns( self, comparator: Callable[[Column, Column], int] = lambda col1, col2: (col1.name > col2.name) - - (col1.name < col2.name), + - (col1.name < col2.name), ) -> Table: """ Sort the columns of a `Table` with the given comparator and return a new `Table`. The original table is not @@ -923,6 +923,7 @@ def tag_columns(self, target_name: str, feature_names: Optional[list[str]] = Non """ # pylint: disable=import-outside-toplevel from ._tagged_table import TaggedTable + return TaggedTable(self._data, target_name, feature_names, self._schema) def transform_column(self, name: str, transformer: Callable[[Row], Any]) -> Table: diff --git a/src/safeds/data/tabular/containers/_tagged_table.py b/src/safeds/data/tabular/containers/_tagged_table.py index 2cb0edc58..bc0050874 100644 --- a/src/safeds/data/tabular/containers/_tagged_table.py +++ b/src/safeds/data/tabular/containers/_tagged_table.py @@ -1,8 +1,7 @@ from typing import Iterable, Optional from IPython.core.display_functions import DisplayHandle - -from safeds.data.tabular.containers import Table, Column +from safeds.data.tabular.containers import Column, Table from safeds.data.tabular.typing import TableSchema @@ -27,7 +26,7 @@ def __init__( data: Iterable, target_name: str, feature_names: Optional[list[str]] = None, - schema: Optional[TableSchema] = None + schema: Optional[TableSchema] = None, ): # Validate input if feature_names is not None: @@ -38,7 +37,9 @@ def __init__( super().__init__(data, schema) - self._features: Table = self.drop_columns([target_name]) if feature_names is None else self.keep_only_columns(feature_names) + self._features: Table = ( + self.drop_columns([target_name]) if feature_names is None else self.keep_only_columns(feature_names) + ) self._target: Column = self.get_column(target_name) @property diff --git a/src/safeds/data/tabular/transformation/_table_transformer.py b/src/safeds/data/tabular/transformation/_table_transformer.py index 3b3248eb1..b939fe1e9 100644 --- a/src/safeds/data/tabular/transformation/_table_transformer.py +++ b/src/safeds/data/tabular/transformation/_table_transformer.py @@ -1,7 +1,7 @@ from __future__ import annotations from abc import ABC, abstractmethod -from typing import Optional, TYPE_CHECKING +from typing import TYPE_CHECKING, Optional if TYPE_CHECKING: from safeds.data.tabular.containers import Table diff --git a/tests/safeds/data/tabular/containers/test_tagged_table.py b/tests/safeds/data/tabular/containers/test_tagged_table.py index dbb513234..cdf56eca2 100644 --- a/tests/safeds/data/tabular/containers/test_tagged_table.py +++ b/tests/safeds/data/tabular/containers/test_tagged_table.py @@ -1,6 +1,5 @@ import pytest - -from safeds.data.tabular.containers import Table, TaggedTable, Column +from safeds.data.tabular.containers import Column, Table, TaggedTable from safeds.exceptions import UnknownColumnNameError From 20215f55427c44b53cdfa9b0f4d14751ba80817c Mon Sep 17 00:00:00 2001 From: Lars Reimann Date: Wed, 29 Mar 2023 14:46:35 +0200 Subject: [PATCH 05/14] test: adjust tests to API changes --- src/safeds/ml/_util_sklearn.py | 2 +- tests/safeds/ml/classification/test_ada_boost.py | 4 ++-- tests/safeds/ml/classification/test_classifier.py | 10 +++++----- tests/safeds/ml/classification/test_decision_tree.py | 4 ++-- .../safeds/ml/classification/test_gradient_boosting.py | 4 ++-- .../ml/classification/test_k_nearest_neighbors.py | 4 ++-- .../ml/classification/test_logistic_regression.py | 4 ++-- tests/safeds/ml/classification/test_random_forest.py | 4 ++-- tests/safeds/ml/regression/test_ada_boost.py | 4 ++-- tests/safeds/ml/regression/test_decision_tree.py | 4 ++-- tests/safeds/ml/regression/test_elastic_net.py | 4 ++-- tests/safeds/ml/regression/test_gradient_boosting.py | 4 ++-- tests/safeds/ml/regression/test_k_nearest_neighbors.py | 4 ++-- tests/safeds/ml/regression/test_lasso_regression.py | 4 ++-- tests/safeds/ml/regression/test_linear_regression.py | 4 ++-- tests/safeds/ml/regression/test_random_forest.py | 4 ++-- tests/safeds/ml/regression/test_regressor.py | 8 +++----- tests/safeds/ml/regression/test_ridge_regression.py | 4 ++-- 18 files changed, 39 insertions(+), 41 deletions(-) diff --git a/src/safeds/ml/_util_sklearn.py b/src/safeds/ml/_util_sklearn.py index a403682f7..df270337b 100644 --- a/src/safeds/ml/_util_sklearn.py +++ b/src/safeds/ml/_util_sklearn.py @@ -71,7 +71,7 @@ def predict(model: Any, dataset: Table, target_name: Optional[str]) -> TaggedTab f"Dataset already contains '{target_name}' column. Please rename this column" ) result_set[target_name] = predicted_target_vector - return TaggedTable(Table(result_set), target_name=target_name) + return Table(result_set).tag_columns(target_name=target_name) except NotFittedError as exception: raise PredictionError("The model was not trained") from exception except ValueError as exception: diff --git a/tests/safeds/ml/classification/test_ada_boost.py b/tests/safeds/ml/classification/test_ada_boost.py index 256ed7e10..f874b4767 100644 --- a/tests/safeds/ml/classification/test_ada_boost.py +++ b/tests/safeds/ml/classification/test_ada_boost.py @@ -13,13 +13,13 @@ def classifier() -> Classifier: @pytest.fixture() def valid_data() -> TaggedTable: table = Table.from_csv_file(resolve_resource_path("test_ada_boost.csv")) - return TaggedTable(table, "T") + return table.tag_columns(target_name="T") @pytest.fixture() def invalid_data() -> TaggedTable: table = Table.from_csv_file(resolve_resource_path("test_ada_boost_invalid.csv")) - return TaggedTable(table, "T") + return table.tag_columns(target_name="T") class TestFit: diff --git a/tests/safeds/ml/classification/test_classifier.py b/tests/safeds/ml/classification/test_classifier.py index c07906861..be48ab662 100644 --- a/tests/safeds/ml/classification/test_classifier.py +++ b/tests/safeds/ml/classification/test_classifier.py @@ -27,20 +27,20 @@ def predict(self, dataset: Table) -> TaggedTable: feature = predicted.rename("feature") dataset = Table.from_columns([feature, predicted]) - return TaggedTable(dataset, target_name="predicted") + return dataset.tag_columns(target_name="predicted") class TestAccuracy: def test_with_same_type(self) -> None: - c1 = Column("predicted", pd.Series(data=[1, 2, 3, 4])) - c2 = Column("expected", pd.Series(data=[1, 2, 3, 3])) - table = TaggedTable(Table.from_columns([c1, c2]), target_name="expected") + c1 = Column("predicted", [1, 2, 3, 4]) + c2 = Column("expected", [1, 2, 3, 3]) + table = Table.from_columns([c1, c2]).tag_columns(target_name="expected") assert DummyClassifier().accuracy(table) == 0.75 def test_with_different_types(self) -> None: c1 = Column("predicted", pd.Series(data=["1", "2", "3", "4"])) c2 = Column("expected", pd.Series(data=[1, 2, 3, 3])) - table = TaggedTable(Table.from_columns([c1, c2]), target_name="expected") + table = Table.from_columns([c1, c2]).tag_columns(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 index 1e11bd3ae..42fb26858 100644 --- a/tests/safeds/ml/classification/test_decision_tree.py +++ b/tests/safeds/ml/classification/test_decision_tree.py @@ -13,13 +13,13 @@ def classifier() -> Classifier: @pytest.fixture() def valid_data() -> TaggedTable: table = Table.from_csv_file(resolve_resource_path("test_decision_tree.csv")) - return TaggedTable(table, "T") + return table.tag_columns(target_name="T") @pytest.fixture() def invalid_data() -> TaggedTable: table = Table.from_csv_file(resolve_resource_path("test_decision_tree_invalid.csv")) - return TaggedTable(table, "T") + return table.tag_columns(target_name="T") class TestFit: diff --git a/tests/safeds/ml/classification/test_gradient_boosting.py b/tests/safeds/ml/classification/test_gradient_boosting.py index 020f98011..b24228a9d 100644 --- a/tests/safeds/ml/classification/test_gradient_boosting.py +++ b/tests/safeds/ml/classification/test_gradient_boosting.py @@ -13,13 +13,13 @@ def classifier() -> Classifier: @pytest.fixture() def valid_data() -> TaggedTable: table = Table.from_csv_file(resolve_resource_path("test_gradient_boosting_classification.csv")) - return TaggedTable(table, "T") + return table.tag_columns(target_name="T") @pytest.fixture() def invalid_data() -> TaggedTable: table = Table.from_csv_file(resolve_resource_path("test_gradient_boosting_classification_invalid.csv")) - return TaggedTable(table, "T") + return table.tag_columns(target_name="T") class TestFit: diff --git a/tests/safeds/ml/classification/test_k_nearest_neighbors.py b/tests/safeds/ml/classification/test_k_nearest_neighbors.py index a7394e6c4..bb6f68b1e 100644 --- a/tests/safeds/ml/classification/test_k_nearest_neighbors.py +++ b/tests/safeds/ml/classification/test_k_nearest_neighbors.py @@ -13,13 +13,13 @@ def classifier() -> Classifier: @pytest.fixture() def valid_data() -> TaggedTable: table = Table.from_csv_file(resolve_resource_path("test_k_nearest_neighbors.csv")) - return TaggedTable(table, "T") + return table.tag_columns(target_name="T") @pytest.fixture() def invalid_data() -> TaggedTable: table = Table.from_csv_file(resolve_resource_path("test_k_nearest_neighbors_invalid.csv")) - return TaggedTable(table, "T") + return table.tag_columns(target_name="T") class TestFit: diff --git a/tests/safeds/ml/classification/test_logistic_regression.py b/tests/safeds/ml/classification/test_logistic_regression.py index 9da5c1507..5dbaa5960 100644 --- a/tests/safeds/ml/classification/test_logistic_regression.py +++ b/tests/safeds/ml/classification/test_logistic_regression.py @@ -13,13 +13,13 @@ def classifier() -> Classifier: @pytest.fixture() def valid_data() -> TaggedTable: table = Table.from_csv_file(resolve_resource_path("test_logistic_regression.csv")) - return TaggedTable(table, "T") + return table.tag_columns(target_name="T") @pytest.fixture() def invalid_data() -> TaggedTable: table = Table.from_csv_file(resolve_resource_path("test_logistic_regression_invalid.csv")) - return TaggedTable(table, "T") + return table.tag_columns(target_name="T") class TestFit: diff --git a/tests/safeds/ml/classification/test_random_forest.py b/tests/safeds/ml/classification/test_random_forest.py index 37d65948a..266d39f0d 100644 --- a/tests/safeds/ml/classification/test_random_forest.py +++ b/tests/safeds/ml/classification/test_random_forest.py @@ -13,13 +13,13 @@ def classifier() -> Classifier: @pytest.fixture() def valid_data() -> TaggedTable: table = Table.from_csv_file(resolve_resource_path("test_random_forest.csv")) - return TaggedTable(table, "T") + return table.tag_columns(target_name="T") @pytest.fixture() def invalid_data() -> TaggedTable: table = Table.from_csv_file(resolve_resource_path("test_random_forest_invalid.csv")) - return TaggedTable(table, "T") + return table.tag_columns(target_name="T") class TestFit: diff --git a/tests/safeds/ml/regression/test_ada_boost.py b/tests/safeds/ml/regression/test_ada_boost.py index d23a01904..db2e15d18 100644 --- a/tests/safeds/ml/regression/test_ada_boost.py +++ b/tests/safeds/ml/regression/test_ada_boost.py @@ -13,13 +13,13 @@ def regressor() -> Regressor: @pytest.fixture() def valid_data() -> TaggedTable: table = Table.from_csv_file(resolve_resource_path("test_ada_boost.csv")) - return TaggedTable(table, "T") + return table.tag_columns(target_name="T") @pytest.fixture() def invalid_data() -> TaggedTable: table = Table.from_csv_file(resolve_resource_path("test_ada_boost_invalid.csv")) - return TaggedTable(table, "T") + return table.tag_columns(target_name="T") class TestFit: diff --git a/tests/safeds/ml/regression/test_decision_tree.py b/tests/safeds/ml/regression/test_decision_tree.py index daa036540..13537681d 100644 --- a/tests/safeds/ml/regression/test_decision_tree.py +++ b/tests/safeds/ml/regression/test_decision_tree.py @@ -13,13 +13,13 @@ def regressor() -> Regressor: @pytest.fixture() def valid_data() -> TaggedTable: table = Table.from_csv_file(resolve_resource_path("test_decision_tree.csv")) - return TaggedTable(table, "T") + return table.tag_columns(target_name="T") @pytest.fixture() def invalid_data() -> TaggedTable: table = Table.from_csv_file(resolve_resource_path("test_decision_tree_invalid.csv")) - return TaggedTable(table, "T") + return table.tag_columns(target_name="T") class TestFit: diff --git a/tests/safeds/ml/regression/test_elastic_net.py b/tests/safeds/ml/regression/test_elastic_net.py index a935a1037..9d4da822a 100644 --- a/tests/safeds/ml/regression/test_elastic_net.py +++ b/tests/safeds/ml/regression/test_elastic_net.py @@ -13,13 +13,13 @@ def regressor() -> Regressor: @pytest.fixture() def valid_data() -> TaggedTable: table = Table.from_csv_file(resolve_resource_path("test_elastic_net_regression.csv")) - return TaggedTable(table, "T") + return table.tag_columns(target_name="T") @pytest.fixture() def invalid_data() -> TaggedTable: table = Table.from_csv_file(resolve_resource_path("test_elastic_net_regression_invalid.csv")) - return TaggedTable(table, "T") + return table.tag_columns(target_name="T") class TestFit: diff --git a/tests/safeds/ml/regression/test_gradient_boosting.py b/tests/safeds/ml/regression/test_gradient_boosting.py index 8f4e06041..b432cc185 100644 --- a/tests/safeds/ml/regression/test_gradient_boosting.py +++ b/tests/safeds/ml/regression/test_gradient_boosting.py @@ -13,13 +13,13 @@ def regressor() -> Regressor: @pytest.fixture() def valid_data() -> TaggedTable: table = Table.from_csv_file(resolve_resource_path("test_gradient_boosting_regression.csv")) - return TaggedTable(table, "T") + return table.tag_columns(target_name="T") @pytest.fixture() def invalid_data() -> TaggedTable: table = Table.from_csv_file(resolve_resource_path("test_gradient_boosting_regression_invalid.csv")) - return TaggedTable(table, "T") + return table.tag_columns(target_name="T") class TestFit: diff --git a/tests/safeds/ml/regression/test_k_nearest_neighbors.py b/tests/safeds/ml/regression/test_k_nearest_neighbors.py index 6e879e54e..f68ea803d 100644 --- a/tests/safeds/ml/regression/test_k_nearest_neighbors.py +++ b/tests/safeds/ml/regression/test_k_nearest_neighbors.py @@ -13,13 +13,13 @@ def regressor() -> Regressor: @pytest.fixture() def valid_data() -> TaggedTable: table = Table.from_csv_file(resolve_resource_path("test_k_nearest_neighbors.csv")) - return TaggedTable(table, "T") + return table.tag_columns(target_name="T") @pytest.fixture() def invalid_data() -> TaggedTable: table = Table.from_csv_file(resolve_resource_path("test_k_nearest_neighbors_invalid.csv")) - return TaggedTable(table, "T") + return table.tag_columns(target_name="T") class TestFit: diff --git a/tests/safeds/ml/regression/test_lasso_regression.py b/tests/safeds/ml/regression/test_lasso_regression.py index 6eb94ac4a..3f49f111e 100644 --- a/tests/safeds/ml/regression/test_lasso_regression.py +++ b/tests/safeds/ml/regression/test_lasso_regression.py @@ -13,13 +13,13 @@ def regressor() -> Regressor: @pytest.fixture() def valid_data() -> TaggedTable: table = Table.from_csv_file(resolve_resource_path("test_lasso_regression.csv")) - return TaggedTable(table, "T") + return table.tag_columns(target_name="T") @pytest.fixture() def invalid_data() -> TaggedTable: table = Table.from_csv_file(resolve_resource_path("test_lasso_regression_invalid.csv")) - return TaggedTable(table, "T") + return table.tag_columns(target_name="T") class TestFit: diff --git a/tests/safeds/ml/regression/test_linear_regression.py b/tests/safeds/ml/regression/test_linear_regression.py index 56d3916c8..d5e705dfc 100644 --- a/tests/safeds/ml/regression/test_linear_regression.py +++ b/tests/safeds/ml/regression/test_linear_regression.py @@ -13,13 +13,13 @@ def regressor() -> Regressor: @pytest.fixture() def valid_data() -> TaggedTable: table = Table.from_csv_file(resolve_resource_path("test_linear_regression.csv")) - return TaggedTable(table, "T") + return table.tag_columns(target_name="T") @pytest.fixture() def invalid_data() -> TaggedTable: table = Table.from_csv_file(resolve_resource_path("test_linear_regression_invalid.csv")) - return TaggedTable(table, "T") + return table.tag_columns(target_name="T") class TestFit: diff --git a/tests/safeds/ml/regression/test_random_forest.py b/tests/safeds/ml/regression/test_random_forest.py index f22846d7d..3f63878fe 100644 --- a/tests/safeds/ml/regression/test_random_forest.py +++ b/tests/safeds/ml/regression/test_random_forest.py @@ -13,13 +13,13 @@ def regressor() -> Regressor: @pytest.fixture() def valid_data() -> TaggedTable: table = Table.from_csv_file(resolve_resource_path("test_random_forest.csv")) - return TaggedTable(table, "T") + return table.tag_columns(target_name="T") @pytest.fixture() def invalid_data() -> TaggedTable: table = Table.from_csv_file(resolve_resource_path("test_random_forest_invalid.csv")) - return TaggedTable(table, "T") + return table.tag_columns(target_name="T") class TestFit: diff --git a/tests/safeds/ml/regression/test_regressor.py b/tests/safeds/ml/regression/test_regressor.py index 6a8926cda..ca802490c 100644 --- a/tests/safeds/ml/regression/test_regressor.py +++ b/tests/safeds/ml/regression/test_regressor.py @@ -32,7 +32,7 @@ def predict(self, dataset: Table) -> TaggedTable: feature = predicted.rename("feature") dataset = Table.from_columns([feature, predicted]) - return TaggedTable(dataset, target_name="predicted") + return dataset.tag_columns(target_name="predicted") class TestMeanAbsoluteError: @@ -49,8 +49,7 @@ class TestMeanAbsoluteError: 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]), + table = Table.from_columns([predicted_column, expected_column]).tag_columns( target_name="expected", ) @@ -65,8 +64,7 @@ class TestMeanSquaredError: 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]), + table = Table.from_columns([predicted_column, expected_column]).tag_columns( target_name="expected", ) diff --git a/tests/safeds/ml/regression/test_ridge_regression.py b/tests/safeds/ml/regression/test_ridge_regression.py index f0b9bfe6e..f5ff7a93d 100644 --- a/tests/safeds/ml/regression/test_ridge_regression.py +++ b/tests/safeds/ml/regression/test_ridge_regression.py @@ -13,13 +13,13 @@ def regressor() -> Regressor: @pytest.fixture() def valid_data() -> TaggedTable: table = Table.from_csv_file(resolve_resource_path("test_ridge_regression.csv")) - return TaggedTable(table, "T") + return table.tag_columns(target_name="T") @pytest.fixture() def invalid_data() -> TaggedTable: table = Table.from_csv_file(resolve_resource_path("test_ridge_regression_invalid.csv")) - return TaggedTable(table, "T") + return table.tag_columns(target_name="T") class TestFit: From 62feb836af77d030339b7c52c90845db19709c64 Mon Sep 17 00:00:00 2001 From: Lars Reimann Date: Wed, 29 Mar 2023 14:49:18 +0200 Subject: [PATCH 06/14] docs: adjust to API changes --- docs/tutorials/machine_learning.ipynb | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/tutorials/machine_learning.ipynb b/docs/tutorials/machine_learning.ipynb index 809b85df5..2a172ec27 100644 --- a/docs/tutorials/machine_learning.ipynb +++ b/docs/tutorials/machine_learning.ipynb @@ -10,8 +10,7 @@ "## Create a `TaggedTable`\n", "\n", "First, we need to create a `TaggedTable` from the training data. `TaggedTable`s are used to train supervised machine learning models, because they keep track of the target\n", - "column. A `TaggedTable` can be created from a `Table` by\n", - "specifying the target column in the `Table`." + "column. A `TaggedTable` can be created from a `Table` calling the `tag_columns` method:" ], "metadata": { "collapsed": false @@ -32,8 +31,7 @@ " \"result\": [6, 7, 10, 13, 9]\n", "})\n", "\n", - "tagged_table = TaggedTable(\n", - " training_set,\n", + "tagged_table = training_set.tag_columns(\n", " target_name=\"result\"\n", ")" ], From a8ce80d1b2093778df93c1b77e35378cec9b0a0a Mon Sep 17 00:00:00 2001 From: lars-reimann Date: Wed, 29 Mar 2023 12:51:00 +0000 Subject: [PATCH 07/14] style: apply automated linter fixes --- src/safeds/ml/_util_sklearn.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/safeds/ml/_util_sklearn.py b/src/safeds/ml/_util_sklearn.py index df270337b..d184bbfaf 100644 --- a/src/safeds/ml/_util_sklearn.py +++ b/src/safeds/ml/_util_sklearn.py @@ -67,9 +67,7 @@ def predict(model: Any, dataset: Table, target_name: Optional[str]) -> TaggedTab predicted_target_vector = model.predict(dataset_df.values) result_set = dataset_df.copy(deep=True) if target_name in result_set.columns: - raise ValueError( - f"Dataset already contains '{target_name}' column. Please rename this column" - ) + raise ValueError(f"Dataset already contains '{target_name}' column. Please rename this column") result_set[target_name] = predicted_target_vector return Table(result_set).tag_columns(target_name=target_name) except NotFittedError as exception: From 67e3bb97a09e49d12c2a0dbd575272f24d83493d Mon Sep 17 00:00:00 2001 From: Lars Reimann Date: Wed, 29 Mar 2023 16:07:38 +0200 Subject: [PATCH 08/14] WIP --- .../data/tabular/containers/_tagged_table.py | 21 +++++++----- src/safeds/ml/_util_sklearn.py | 20 +++++------ src/safeds/ml/classification/_ada_boost.py | 4 ++- .../ml/classification/_decision_tree.py | 4 ++- .../_gradient_boosting_classification.py | 4 ++- .../ml/classification/_k_nearest_neighbors.py | 8 ++--- .../ml/classification/_logistic_regression.py | 4 ++- .../ml/classification/_random_forest.py | 4 ++- src/safeds/ml/regression/_ada_boost.py | 4 ++- src/safeds/ml/regression/_decision_tree.py | 4 ++- .../ml/regression/_elastic_net_regression.py | 4 ++- .../_gradient_boosting_regression.py | 4 ++- .../ml/regression/_k_nearest_neighbors.py | 4 ++- src/safeds/ml/regression/_lasso_regression.py | 4 ++- .../ml/regression/_linear_regression.py | 4 ++- src/safeds/ml/regression/_random_forest.py | 4 ++- src/safeds/ml/regression/_ridge_regression.py | 4 ++- tests/{fixtures => helpers}/__init__.py | 0 tests/{fixtures => helpers}/_resources.py | 0 tests/resources/test_ada_boost.csv | 3 -- tests/resources/test_ada_boost_invalid.csv | 3 -- .../containers/_row/test_has_column.py | 2 +- .../containers/_table/test_column_drop.py | 2 +- .../_table/test_drop_duplicate_rows.py | 2 +- .../containers/_table/test_from_columns.py | 2 +- .../containers/_table/test_from_csv_file.py | 2 +- .../containers/_table/test_from_json_file.py | 2 +- .../containers/_table/test_from_rows.py | 2 +- .../tabular/containers/_table/test_get_row.py | 2 +- .../containers/_table/test_has_column.py | 2 +- .../_table/test_keep_only_columns.py | 2 +- .../tabular/containers/_table/test_rename.py | 2 +- .../containers/_table/test_replace_column.py | 2 +- .../_table/test_table_add_column.py | 2 +- .../containers/_table/test_to_columns.py | 2 +- .../tabular/containers/_table/test_to_rows.py | 2 +- .../_table/test_transform_column.py | 2 +- .../tabular/containers/test_tagged_table.py | 8 ++++- .../_table_schema/test_get_column_type.py | 2 +- .../typing/_table_schema/test_has_column.py | 2 +- .../typing/_table_schema/test_table_equals.py | 2 +- .../ml/classification/test_ada_boost.py | 26 ++++++++++---- .../ml/classification/test_decision_tree.py | 2 +- .../classification/test_gradient_boosting.py | 2 +- .../test_k_nearest_neighbors.py | 2 +- .../test_logistic_regression.py | 2 +- .../ml/classification/test_random_forest.py | 2 +- tests/safeds/ml/regression/test_ada_boost.py | 34 +++++++++++++++---- .../ml/regression/test_decision_tree.py | 2 +- .../safeds/ml/regression/test_elastic_net.py | 2 +- .../ml/regression/test_gradient_boosting.py | 2 +- .../ml/regression/test_k_nearest_neighbors.py | 2 +- .../ml/regression/test_lasso_regression.py | 2 +- .../ml/regression/test_linear_regression.py | 2 +- .../ml/regression/test_random_forest.py | 2 +- .../ml/regression/test_ridge_regression.py | 2 +- tests/safeds/ml/test_util_sklearn.py | 2 +- 57 files changed, 152 insertions(+), 93 deletions(-) rename tests/{fixtures => helpers}/__init__.py (100%) rename tests/{fixtures => helpers}/_resources.py (100%) delete mode 100644 tests/resources/test_ada_boost.csv delete mode 100644 tests/resources/test_ada_boost_invalid.csv diff --git a/src/safeds/data/tabular/containers/_tagged_table.py b/src/safeds/data/tabular/containers/_tagged_table.py index bc0050874..065b8c9be 100644 --- a/src/safeds/data/tabular/containers/_tagged_table.py +++ b/src/safeds/data/tabular/containers/_tagged_table.py @@ -28,18 +28,21 @@ def __init__( feature_names: Optional[list[str]] = None, schema: Optional[TableSchema] = None, ): - # Validate input - if feature_names is not None: + super().__init__(data, schema) + + # If no feature names are specified, use all columns except the target column + if feature_names is None: + feature_names = self.get_column_names() if target_name in feature_names: - raise ValueError(f"Column '{target_name}' cannot be both feature and target.") - if len(feature_names) == 0: - raise ValueError("At least one feature column must be specified.") + feature_names.remove(target_name) - super().__init__(data, schema) + # Validate inputs + if target_name in feature_names: + raise ValueError(f"Column '{target_name}' cannot be both feature and target.") + if len(feature_names) == 0: + raise ValueError("At least one feature column must be specified.") - self._features: Table = ( - self.drop_columns([target_name]) if feature_names is None else self.keep_only_columns(feature_names) - ) + self._features: Table = self.keep_only_columns(feature_names) self._target: Column = self.get_column(target_name) @property diff --git a/src/safeds/ml/_util_sklearn.py b/src/safeds/ml/_util_sklearn.py index d184bbfaf..9d11c928d 100644 --- a/src/safeds/ml/_util_sklearn.py +++ b/src/safeds/ml/_util_sklearn.py @@ -29,12 +29,10 @@ def fit(model: Any, tagged_table: TaggedTable) -> None: ) except ValueError as exception: raise LearningError(str(exception)) from exception - except Exception as exception: - raise LearningError(None) from exception # noinspection PyProtectedMember -def predict(model: Any, dataset: Table, target_name: Optional[str]) -> TaggedTable: +def predict(model: Any, dataset: Table, feature_names: Optional[list[str]], target_name: Optional[str]) -> TaggedTable: """ Predict a target vector using a dataset containing feature vectors. The model has to be trained first. @@ -44,8 +42,10 @@ def predict(model: Any, dataset: Table, target_name: Optional[str]) -> TaggedTab Classifier or regressor from scikit-learn. dataset : Table The dataset containing the features. - target_name : str + target_name : Optional[str] The name of the target column. + feature_names : Optional[list[str]] + The names of the feature columns. Returns ------- @@ -58,21 +58,19 @@ def predict(model: Any, dataset: Table, target_name: Optional[str]) -> TaggedTab If predicting with the given dataset failed. """ - if model is None or target_name is None: + if model is None or target_name is None or feature_names is None: raise PredictionError("The model was not trained") - dataset_df = dataset._data - dataset_df.columns = dataset.schema.get_column_names() + dataset_df = dataset.keep_only_columns(feature_names)._data + dataset_df.columns = feature_names try: predicted_target_vector = model.predict(dataset_df.values) - result_set = dataset_df.copy(deep=True) + result_set = dataset._data.copy(deep=True) if target_name in result_set.columns: raise ValueError(f"Dataset already contains '{target_name}' column. Please rename this column") result_set[target_name] = predicted_target_vector - return Table(result_set).tag_columns(target_name=target_name) + return Table(result_set).tag_columns(target_name=target_name, feature_names=feature_names) except NotFittedError as exception: raise PredictionError("The model was not trained") from exception except ValueError as exception: raise PredictionError(str(exception)) from exception - except Exception as exception: - raise PredictionError(None) from exception diff --git a/src/safeds/ml/classification/_ada_boost.py b/src/safeds/ml/classification/_ada_boost.py index 4c6080d65..229015b5a 100644 --- a/src/safeds/ml/classification/_ada_boost.py +++ b/src/safeds/ml/classification/_ada_boost.py @@ -17,6 +17,7 @@ class AdaBoost(Classifier): def __init__(self) -> None: self._wrapped_classifier: Optional[sk_AdaBoostClassifier] = None + self._feature_names: Optional[list[str]] = None self._target_name: Optional[str] = None def fit(self, training_set: TaggedTable) -> AdaBoost: @@ -45,6 +46,7 @@ def fit(self, training_set: TaggedTable) -> AdaBoost: result = AdaBoost() result._wrapped_classifier = wrapped_classifier + result._feature_names = training_set.features.get_column_names() result._target_name = training_set.target.name return result @@ -68,4 +70,4 @@ def predict(self, dataset: Table) -> TaggedTable: PredictionError If prediction with the given dataset failed. """ - return predict(self._wrapped_classifier, dataset, self._target_name) + return predict(self._wrapped_classifier, dataset, self._feature_names, self._target_name) diff --git a/src/safeds/ml/classification/_decision_tree.py b/src/safeds/ml/classification/_decision_tree.py index aa83ee77b..47d093507 100644 --- a/src/safeds/ml/classification/_decision_tree.py +++ b/src/safeds/ml/classification/_decision_tree.py @@ -17,6 +17,7 @@ class DecisionTree(Classifier): def __init__(self) -> None: self._wrapped_classifier: Optional[sk_DecisionTreeClassifier] = None + self._feature_names: Optional[list[str]] = None self._target_name: Optional[str] = None def fit(self, training_set: TaggedTable) -> DecisionTree: @@ -45,6 +46,7 @@ def fit(self, training_set: TaggedTable) -> DecisionTree: result = DecisionTree() result._wrapped_classifier = wrapped_classifier + result._feature_names = training_set.features.get_column_names() result._target_name = training_set.target.name return result @@ -68,4 +70,4 @@ def predict(self, dataset: Table) -> TaggedTable: PredictionError If prediction with the given dataset failed. """ - return predict(self._wrapped_classifier, dataset, self._target_name) + return predict(self._wrapped_classifier, dataset, self._feature_names, self._target_name) diff --git a/src/safeds/ml/classification/_gradient_boosting_classification.py b/src/safeds/ml/classification/_gradient_boosting_classification.py index 4252783a9..74dc7cb7d 100644 --- a/src/safeds/ml/classification/_gradient_boosting_classification.py +++ b/src/safeds/ml/classification/_gradient_boosting_classification.py @@ -17,6 +17,7 @@ class GradientBoosting(Classifier): def __init__(self) -> None: self._wrapped_classifier: Optional[sk_GradientBoostingClassifier] = None + self._feature_names: Optional[list[str]] = None self._target_name: Optional[str] = None def fit(self, training_set: TaggedTable) -> GradientBoosting: @@ -45,6 +46,7 @@ def fit(self, training_set: TaggedTable) -> GradientBoosting: result = GradientBoosting() result._wrapped_classifier = wrapped_classifier + result._feature_names = training_set.features.get_column_names() result._target_name = training_set.target.name return result @@ -69,4 +71,4 @@ def predict(self, dataset: Table) -> TaggedTable: PredictionError If prediction with the given dataset failed. """ - return predict(self._wrapped_classifier, dataset, self._target_name) + return predict(self._wrapped_classifier, dataset, self._feature_names, self._target_name) diff --git a/src/safeds/ml/classification/_k_nearest_neighbors.py b/src/safeds/ml/classification/_k_nearest_neighbors.py index 7a0c7a12f..e2d7cd915 100644 --- a/src/safeds/ml/classification/_k_nearest_neighbors.py +++ b/src/safeds/ml/classification/_k_nearest_neighbors.py @@ -23,6 +23,7 @@ def __init__(self, n_neighbors: int) -> None: self._n_neighbors = n_neighbors self._wrapped_classifier: Optional[sk_KNeighborsClassifier] = None + self._feature_names: Optional[list[str]] = None self._target_name: Optional[str] = None def fit(self, training_set: TaggedTable) -> KNearestNeighbors: @@ -50,6 +51,7 @@ def fit(self, training_set: TaggedTable) -> KNearestNeighbors: result = KNearestNeighbors(self._n_neighbors) result._wrapped_classifier = wrapped_classifier + result._feature_names = training_set.features.get_column_names() result._target_name = training_set.target.name return result @@ -73,8 +75,4 @@ def predict(self, dataset: Table) -> TaggedTable: PredictionError If prediction with the given dataset failed. """ - return predict( - self._wrapped_classifier, - dataset, - self._target_name, - ) + return predict(self._wrapped_classifier, dataset, self._feature_names, self._target_name) diff --git a/src/safeds/ml/classification/_logistic_regression.py b/src/safeds/ml/classification/_logistic_regression.py index 46fcc102f..5eae1d873 100644 --- a/src/safeds/ml/classification/_logistic_regression.py +++ b/src/safeds/ml/classification/_logistic_regression.py @@ -17,6 +17,7 @@ class LogisticRegression(Classifier): def __init__(self) -> None: self._wrapped_classifier: Optional[sk_LogisticRegression] = None + self._feature_names: Optional[list[str]] = None self._target_name: Optional[str] = None def fit(self, training_set: TaggedTable) -> LogisticRegression: @@ -45,6 +46,7 @@ def fit(self, training_set: TaggedTable) -> LogisticRegression: result = LogisticRegression() result._wrapped_classifier = wrapped_classifier + result._feature_names = training_set.features.get_column_names() result._target_name = training_set.target.name return result @@ -68,4 +70,4 @@ def predict(self, dataset: Table) -> TaggedTable: PredictionError If prediction with the given dataset failed. """ - return predict(self._wrapped_classifier, dataset, self._target_name) + return predict(self._wrapped_classifier, dataset, self._feature_names, self._target_name) diff --git a/src/safeds/ml/classification/_random_forest.py b/src/safeds/ml/classification/_random_forest.py index 9f8928f94..927cc9397 100644 --- a/src/safeds/ml/classification/_random_forest.py +++ b/src/safeds/ml/classification/_random_forest.py @@ -16,6 +16,7 @@ class RandomForest(Classifier): def __init__(self) -> None: self._wrapped_classifier: Optional[sk_RandomForestClassifier] = None + self._feature_names: Optional[list[str]] = None self._target_name: Optional[str] = None def fit(self, training_set: TaggedTable) -> RandomForest: @@ -44,6 +45,7 @@ def fit(self, training_set: TaggedTable) -> RandomForest: result = RandomForest() result._wrapped_classifier = wrapped_classifier + result._feature_names = training_set.features.get_column_names() result._target_name = training_set.target.name return result @@ -67,4 +69,4 @@ def predict(self, dataset: Table) -> TaggedTable: PredictionError If prediction with the given dataset failed. """ - return predict(self._wrapped_classifier, dataset, self._target_name) + return predict(self._wrapped_classifier, dataset, self._feature_names, self._target_name) diff --git a/src/safeds/ml/regression/_ada_boost.py b/src/safeds/ml/regression/_ada_boost.py index 52d1d42f3..fcd9dbce2 100644 --- a/src/safeds/ml/regression/_ada_boost.py +++ b/src/safeds/ml/regression/_ada_boost.py @@ -17,6 +17,7 @@ class AdaBoost(Regressor): def __init__(self) -> None: self._wrapped_regressor: Optional[sk_AdaBoostRegressor] = None + self._feature_names: Optional[list[str]] = None self._target_name: Optional[str] = None def fit(self, training_set: TaggedTable) -> AdaBoost: @@ -45,6 +46,7 @@ def fit(self, training_set: TaggedTable) -> AdaBoost: result = AdaBoost() result._wrapped_regressor = wrapped_regressor + result._feature_names = training_set.features.get_column_names() result._target_name = training_set.target.name return result @@ -68,4 +70,4 @@ def predict(self, dataset: Table) -> TaggedTable: PredictionError If prediction with the given dataset failed. """ - return predict(self._wrapped_regressor, dataset, self._target_name) + return predict(self._wrapped_regressor, dataset, self._feature_names, self._target_name) diff --git a/src/safeds/ml/regression/_decision_tree.py b/src/safeds/ml/regression/_decision_tree.py index 5b71d8374..0fcaaef08 100644 --- a/src/safeds/ml/regression/_decision_tree.py +++ b/src/safeds/ml/regression/_decision_tree.py @@ -17,6 +17,7 @@ class DecisionTree(Regressor): def __init__(self) -> None: self._wrapped_regressor: Optional[sk_DecisionTreeRegressor] = None + self._feature_names: Optional[list[str]] = None self._target_name: Optional[str] = None def fit(self, training_set: TaggedTable) -> DecisionTree: @@ -45,6 +46,7 @@ def fit(self, training_set: TaggedTable) -> DecisionTree: result = DecisionTree() result._wrapped_regressor = wrapped_regressor + result._feature_names = training_set.features.get_column_names() result._target_name = training_set.target.name return result @@ -68,4 +70,4 @@ def predict(self, dataset: Table) -> TaggedTable: PredictionError If prediction with the given dataset failed. """ - return predict(self._wrapped_regressor, dataset, self._target_name) + return predict(self._wrapped_regressor, dataset, self._feature_names, self._target_name) diff --git a/src/safeds/ml/regression/_elastic_net_regression.py b/src/safeds/ml/regression/_elastic_net_regression.py index 37f548d6a..7d12674dd 100644 --- a/src/safeds/ml/regression/_elastic_net_regression.py +++ b/src/safeds/ml/regression/_elastic_net_regression.py @@ -17,6 +17,7 @@ class ElasticNetRegression(Regressor): def __init__(self) -> None: self._wrapped_regressor: Optional[sk_ElasticNet] = None + self._feature_names: Optional[list[str]] = None self._target_name: Optional[str] = None def fit(self, training_set: TaggedTable) -> ElasticNetRegression: @@ -45,6 +46,7 @@ def fit(self, training_set: TaggedTable) -> ElasticNetRegression: result = ElasticNetRegression() result._wrapped_regressor = wrapped_regressor + result._feature_names = training_set.features.get_column_names() result._target_name = training_set.target.name return result @@ -68,4 +70,4 @@ def predict(self, dataset: Table) -> TaggedTable: PredictionError If prediction with the given dataset failed """ - return predict(self._wrapped_regressor, dataset, self._target_name) + return predict(self._wrapped_regressor, dataset, self._feature_names, self._target_name) diff --git a/src/safeds/ml/regression/_gradient_boosting_regression.py b/src/safeds/ml/regression/_gradient_boosting_regression.py index c87085d86..abb774567 100644 --- a/src/safeds/ml/regression/_gradient_boosting_regression.py +++ b/src/safeds/ml/regression/_gradient_boosting_regression.py @@ -17,6 +17,7 @@ class GradientBoosting(Regressor): def __init__(self) -> None: self._wrapped_regressor: Optional[sk_GradientBoostingRegressor] = None + self._feature_names: Optional[list[str]] = None self._target_name: Optional[str] = None def fit(self, training_set: TaggedTable) -> GradientBoosting: @@ -45,6 +46,7 @@ def fit(self, training_set: TaggedTable) -> GradientBoosting: result = GradientBoosting() result._wrapped_regressor = wrapped_regressor + result._feature_names = training_set.features.get_column_names() result._target_name = training_set.target.name return result @@ -68,4 +70,4 @@ def predict(self, dataset: Table) -> TaggedTable: PredictionError If prediction with the given dataset failed. """ - return predict(self._wrapped_regressor, dataset, self._target_name) + return predict(self._wrapped_regressor, dataset, self._feature_names, self._target_name) diff --git a/src/safeds/ml/regression/_k_nearest_neighbors.py b/src/safeds/ml/regression/_k_nearest_neighbors.py index c9b5fd3b5..d2371953c 100644 --- a/src/safeds/ml/regression/_k_nearest_neighbors.py +++ b/src/safeds/ml/regression/_k_nearest_neighbors.py @@ -23,6 +23,7 @@ def __init__(self, n_neighbors: int) -> None: self._n_neighbors = n_neighbors self._wrapped_regressor: Optional[sk_KNeighborsRegressor] = None + self._feature_names: Optional[list[str]] = None self._target_name: Optional[str] = None def fit(self, training_set: TaggedTable) -> KNearestNeighbors: @@ -51,6 +52,7 @@ def fit(self, training_set: TaggedTable) -> KNearestNeighbors: result = KNearestNeighbors(self._n_neighbors) result._wrapped_regressor = wrapped_regressor + result._feature_names = training_set.features.get_column_names() result._target_name = training_set.target.name return result @@ -74,4 +76,4 @@ def predict(self, dataset: Table) -> TaggedTable: PredictionError If prediction with the given dataset failed. """ - return predict(self._wrapped_regressor, dataset, self._target_name) + return predict(self._wrapped_regressor, dataset, self._feature_names, self._target_name) diff --git a/src/safeds/ml/regression/_lasso_regression.py b/src/safeds/ml/regression/_lasso_regression.py index 824107481..f4f2f48b4 100644 --- a/src/safeds/ml/regression/_lasso_regression.py +++ b/src/safeds/ml/regression/_lasso_regression.py @@ -17,6 +17,7 @@ class LassoRegression(Regressor): def __init__(self) -> None: self._wrapped_regressor: Optional[sk_Lasso] = None + self._feature_names: Optional[list[str]] = None self._target_name: Optional[str] = None def fit(self, training_set: TaggedTable) -> LassoRegression: @@ -45,6 +46,7 @@ def fit(self, training_set: TaggedTable) -> LassoRegression: result = LassoRegression() result._wrapped_regressor = wrapped_regressor + result._feature_names = training_set.features.get_column_names() result._target_name = training_set.target.name return result @@ -68,4 +70,4 @@ def predict(self, dataset: Table) -> TaggedTable: PredictionError If prediction with the given dataset failed. """ - return predict(self._wrapped_regressor, dataset, self._target_name) + return predict(self._wrapped_regressor, dataset, self._feature_names, self._target_name) diff --git a/src/safeds/ml/regression/_linear_regression.py b/src/safeds/ml/regression/_linear_regression.py index d05286188..1400eb9bc 100644 --- a/src/safeds/ml/regression/_linear_regression.py +++ b/src/safeds/ml/regression/_linear_regression.py @@ -17,6 +17,7 @@ class LinearRegression(Regressor): def __init__(self) -> None: self._wrapped_regressor: Optional[sk_LinearRegression] = None + self._feature_names: Optional[list[str]] = None self._target_name: Optional[str] = None def fit(self, training_set: TaggedTable) -> LinearRegression: @@ -45,6 +46,7 @@ def fit(self, training_set: TaggedTable) -> LinearRegression: result = LinearRegression() result._wrapped_regressor = wrapped_regressor + result._feature_names = training_set.features.get_column_names() result._target_name = training_set.target.name return result @@ -68,4 +70,4 @@ def predict(self, dataset: Table) -> TaggedTable: PredictionError If prediction with the given dataset failed. """ - return predict(self._wrapped_regressor, dataset, self._target_name) + return predict(self._wrapped_regressor, dataset, self._feature_names, self._target_name) diff --git a/src/safeds/ml/regression/_random_forest.py b/src/safeds/ml/regression/_random_forest.py index 9a49b1298..ad6bdc28c 100644 --- a/src/safeds/ml/regression/_random_forest.py +++ b/src/safeds/ml/regression/_random_forest.py @@ -16,6 +16,7 @@ class RandomForest(Regressor): def __init__(self) -> None: self._wrapped_regressor: Optional[sk_RandomForestRegressor] = None + self._feature_names: Optional[list[str]] = None self._target_name: Optional[str] = None def fit(self, training_set: TaggedTable) -> RandomForest: @@ -44,6 +45,7 @@ def fit(self, training_set: TaggedTable) -> RandomForest: result = RandomForest() result._wrapped_regressor = wrapped_regressor + result._feature_names = training_set.features.get_column_names() result._target_name = training_set.target.name return result @@ -67,4 +69,4 @@ def predict(self, dataset: Table) -> TaggedTable: PredictionError If prediction with the given dataset failed. """ - return predict(self._wrapped_regressor, dataset, self._target_name) + return predict(self._wrapped_regressor, dataset, self._feature_names, self._target_name) diff --git a/src/safeds/ml/regression/_ridge_regression.py b/src/safeds/ml/regression/_ridge_regression.py index bfcbe5404..cd3f27fd0 100644 --- a/src/safeds/ml/regression/_ridge_regression.py +++ b/src/safeds/ml/regression/_ridge_regression.py @@ -17,6 +17,7 @@ class RidgeRegression(Regressor): def __init__(self) -> None: self._wrapped_regressor: Optional[sk_Ridge] = None + self._feature_names: Optional[list[str]] = None self._target_name: Optional[str] = None def fit(self, training_set: TaggedTable) -> RidgeRegression: @@ -45,6 +46,7 @@ def fit(self, training_set: TaggedTable) -> RidgeRegression: result = RidgeRegression() result._wrapped_regressor = wrapped_regressor + result._feature_names = training_set.features.get_column_names() result._target_name = training_set.target.name return result @@ -68,4 +70,4 @@ def predict(self, dataset: Table) -> TaggedTable: PredictionError If prediction with the given dataset failed. """ - return predict(self._wrapped_regressor, dataset, self._target_name) + return predict(self._wrapped_regressor, dataset, self._feature_names, self._target_name) diff --git a/tests/fixtures/__init__.py b/tests/helpers/__init__.py similarity index 100% rename from tests/fixtures/__init__.py rename to tests/helpers/__init__.py diff --git a/tests/fixtures/_resources.py b/tests/helpers/_resources.py similarity index 100% rename from tests/fixtures/_resources.py rename to tests/helpers/_resources.py diff --git a/tests/resources/test_ada_boost.csv b/tests/resources/test_ada_boost.csv deleted file mode 100644 index 5ba8f4fad..000000000 --- a/tests/resources/test_ada_boost.csv +++ /dev/null @@ -1,3 +0,0 @@ -A,B,C,T -1,2,3,0 -4,5,6,1 diff --git a/tests/resources/test_ada_boost_invalid.csv b/tests/resources/test_ada_boost_invalid.csv deleted file mode 100644 index cfcf7131d..000000000 --- a/tests/resources/test_ada_boost_invalid.csv +++ /dev/null @@ -1,3 +0,0 @@ -A,B,C,T -A,2,3,0 -4,5,6,1 diff --git a/tests/safeds/data/tabular/containers/_row/test_has_column.py b/tests/safeds/data/tabular/containers/_row/test_has_column.py index a18246328..a776399a5 100644 --- a/tests/safeds/data/tabular/containers/_row/test_has_column.py +++ b/tests/safeds/data/tabular/containers/_row/test_has_column.py @@ -1,5 +1,5 @@ from safeds.data.tabular.containers import Table -from tests.fixtures import resolve_resource_path +from tests.helpers import resolve_resource_path def test_has_column_positive() -> None: diff --git a/tests/safeds/data/tabular/containers/_table/test_column_drop.py b/tests/safeds/data/tabular/containers/_table/test_column_drop.py index 290a5f055..e4ad6efe8 100644 --- a/tests/safeds/data/tabular/containers/_table/test_column_drop.py +++ b/tests/safeds/data/tabular/containers/_table/test_column_drop.py @@ -1,7 +1,7 @@ import pytest from safeds.data.tabular.containers import Table from safeds.exceptions import UnknownColumnNameError -from tests.fixtures import resolve_resource_path +from tests.helpers import resolve_resource_path def test_table_column_drop() -> None: diff --git a/tests/safeds/data/tabular/containers/_table/test_drop_duplicate_rows.py b/tests/safeds/data/tabular/containers/_table/test_drop_duplicate_rows.py index fdfdea451..9bb135662 100644 --- a/tests/safeds/data/tabular/containers/_table/test_drop_duplicate_rows.py +++ b/tests/safeds/data/tabular/containers/_table/test_drop_duplicate_rows.py @@ -1,7 +1,7 @@ import pandas as pd import pytest from safeds.data.tabular.containers import Table -from tests.fixtures import resolve_resource_path +from tests.helpers import resolve_resource_path @pytest.mark.parametrize( diff --git a/tests/safeds/data/tabular/containers/_table/test_from_columns.py b/tests/safeds/data/tabular/containers/_table/test_from_columns.py index 1c9962f95..b44ab9b1a 100644 --- a/tests/safeds/data/tabular/containers/_table/test_from_columns.py +++ b/tests/safeds/data/tabular/containers/_table/test_from_columns.py @@ -2,7 +2,7 @@ import pytest from safeds.data.tabular.containers import Column, Table from safeds.exceptions import MissingDataError -from tests.fixtures import resolve_resource_path +from tests.helpers import resolve_resource_path def test_from_columns() -> None: diff --git a/tests/safeds/data/tabular/containers/_table/test_from_csv_file.py b/tests/safeds/data/tabular/containers/_table/test_from_csv_file.py index 0150e334e..c0dc4899d 100644 --- a/tests/safeds/data/tabular/containers/_table/test_from_csv_file.py +++ b/tests/safeds/data/tabular/containers/_table/test_from_csv_file.py @@ -1,6 +1,6 @@ import pytest from safeds.data.tabular.containers import Table -from tests.fixtures import resolve_resource_path +from tests.helpers import resolve_resource_path def test_from_csv_file_valid() -> None: diff --git a/tests/safeds/data/tabular/containers/_table/test_from_json_file.py b/tests/safeds/data/tabular/containers/_table/test_from_json_file.py index adf3cdf41..a970232da 100644 --- a/tests/safeds/data/tabular/containers/_table/test_from_json_file.py +++ b/tests/safeds/data/tabular/containers/_table/test_from_json_file.py @@ -1,6 +1,6 @@ import pytest from safeds.data.tabular.containers import Table -from tests.fixtures import resolve_resource_path +from tests.helpers import resolve_resource_path def test_from_json_file_valid() -> None: diff --git a/tests/safeds/data/tabular/containers/_table/test_from_rows.py b/tests/safeds/data/tabular/containers/_table/test_from_rows.py index 3e5ebac15..a1c8e934d 100644 --- a/tests/safeds/data/tabular/containers/_table/test_from_rows.py +++ b/tests/safeds/data/tabular/containers/_table/test_from_rows.py @@ -1,7 +1,7 @@ import pytest from safeds.data.tabular.containers import Row, Table from safeds.exceptions import MissingDataError -from tests.fixtures import resolve_resource_path +from tests.helpers import resolve_resource_path def test_from_rows() -> None: diff --git a/tests/safeds/data/tabular/containers/_table/test_get_row.py b/tests/safeds/data/tabular/containers/_table/test_get_row.py index ab457753c..b42976e4b 100644 --- a/tests/safeds/data/tabular/containers/_table/test_get_row.py +++ b/tests/safeds/data/tabular/containers/_table/test_get_row.py @@ -1,7 +1,7 @@ import pytest from safeds.data.tabular.containers import Table from safeds.exceptions import IndexOutOfBoundsError -from tests.fixtures import resolve_resource_path +from tests.helpers import resolve_resource_path def test_get_row() -> None: diff --git a/tests/safeds/data/tabular/containers/_table/test_has_column.py b/tests/safeds/data/tabular/containers/_table/test_has_column.py index 99b224b15..a450c733e 100644 --- a/tests/safeds/data/tabular/containers/_table/test_has_column.py +++ b/tests/safeds/data/tabular/containers/_table/test_has_column.py @@ -1,5 +1,5 @@ from safeds.data.tabular.containers import Table -from tests.fixtures import resolve_resource_path +from tests.helpers import resolve_resource_path def test_has_column_positive() -> None: diff --git a/tests/safeds/data/tabular/containers/_table/test_keep_only_columns.py b/tests/safeds/data/tabular/containers/_table/test_keep_only_columns.py index edc3034d4..939107740 100644 --- a/tests/safeds/data/tabular/containers/_table/test_keep_only_columns.py +++ b/tests/safeds/data/tabular/containers/_table/test_keep_only_columns.py @@ -1,7 +1,7 @@ import pytest from safeds.data.tabular.containers import Table from safeds.exceptions import UnknownColumnNameError -from tests.fixtures import resolve_resource_path +from tests.helpers import resolve_resource_path def test_keep_columns() -> None: diff --git a/tests/safeds/data/tabular/containers/_table/test_rename.py b/tests/safeds/data/tabular/containers/_table/test_rename.py index d3e8ac4ce..69a4a082c 100644 --- a/tests/safeds/data/tabular/containers/_table/test_rename.py +++ b/tests/safeds/data/tabular/containers/_table/test_rename.py @@ -1,7 +1,7 @@ import pytest from safeds.data.tabular.containers import Table from safeds.exceptions import DuplicateColumnNameError, UnknownColumnNameError -from tests.fixtures import resolve_resource_path +from tests.helpers import resolve_resource_path @pytest.mark.parametrize( diff --git a/tests/safeds/data/tabular/containers/_table/test_replace_column.py b/tests/safeds/data/tabular/containers/_table/test_replace_column.py index 23b4875dc..1c211ca3e 100644 --- a/tests/safeds/data/tabular/containers/_table/test_replace_column.py +++ b/tests/safeds/data/tabular/containers/_table/test_replace_column.py @@ -6,7 +6,7 @@ DuplicateColumnNameError, UnknownColumnNameError, ) -from tests.fixtures import resolve_resource_path +from tests.helpers import resolve_resource_path @pytest.mark.parametrize( diff --git a/tests/safeds/data/tabular/containers/_table/test_table_add_column.py b/tests/safeds/data/tabular/containers/_table/test_table_add_column.py index 1cc8c548f..da88bf37d 100644 --- a/tests/safeds/data/tabular/containers/_table/test_table_add_column.py +++ b/tests/safeds/data/tabular/containers/_table/test_table_add_column.py @@ -2,7 +2,7 @@ import pytest from safeds.data.tabular.containers import Column, Table from safeds.exceptions import ColumnSizeError, DuplicateColumnNameError -from tests.fixtures import resolve_resource_path +from tests.helpers import resolve_resource_path def test_table_add_column_valid() -> None: diff --git a/tests/safeds/data/tabular/containers/_table/test_to_columns.py b/tests/safeds/data/tabular/containers/_table/test_to_columns.py index 98cdca33a..4644149e3 100644 --- a/tests/safeds/data/tabular/containers/_table/test_to_columns.py +++ b/tests/safeds/data/tabular/containers/_table/test_to_columns.py @@ -1,7 +1,7 @@ import pandas as pd import pytest from safeds.data.tabular.containers import Column, Table -from tests.fixtures import resolve_resource_path +from tests.helpers import resolve_resource_path @pytest.mark.parametrize( diff --git a/tests/safeds/data/tabular/containers/_table/test_to_rows.py b/tests/safeds/data/tabular/containers/_table/test_to_rows.py index e623dc969..ffdcbc785 100644 --- a/tests/safeds/data/tabular/containers/_table/test_to_rows.py +++ b/tests/safeds/data/tabular/containers/_table/test_to_rows.py @@ -1,7 +1,7 @@ import pandas as pd from safeds.data.tabular.containers import Row, Table from safeds.data.tabular.typing import IntColumnType, StringColumnType, TableSchema -from tests.fixtures import resolve_resource_path +from tests.helpers import resolve_resource_path def test_to_rows() -> None: diff --git a/tests/safeds/data/tabular/containers/_table/test_transform_column.py b/tests/safeds/data/tabular/containers/_table/test_transform_column.py index 227fc8acd..16dc5a3e6 100644 --- a/tests/safeds/data/tabular/containers/_table/test_transform_column.py +++ b/tests/safeds/data/tabular/containers/_table/test_transform_column.py @@ -1,7 +1,7 @@ import pytest from safeds.data.tabular.containers import Table from safeds.exceptions import UnknownColumnNameError -from tests.fixtures import resolve_resource_path +from tests.helpers import resolve_resource_path def test_transform_column_valid() -> None: diff --git a/tests/safeds/data/tabular/containers/test_tagged_table.py b/tests/safeds/data/tabular/containers/test_tagged_table.py index cdf56eca2..73794bdf7 100644 --- a/tests/safeds/data/tabular/containers/test_tagged_table.py +++ b/tests/safeds/data/tabular/containers/test_tagged_table.py @@ -33,10 +33,16 @@ def test_should_raise_if_features_and_target_overlap(self, table: Table) -> None with pytest.raises(ValueError): table.tag_columns(target_name="A", feature_names=["A", "B", "C"]) - def test_should_raise_if_features_are_empty(self, table: Table) -> None: + def test_should_raise_if_features_are_empty_explicitly(self, table: Table) -> None: with pytest.raises(ValueError): table.tag_columns(target_name="A", feature_names=[]) + def test_should_raise_if_features_are_empty_implicitly(self, table: Table) -> None: + table = Table.from_columns([Column("A", [1, 4])]) + + with pytest.raises(ValueError): + table.tag_columns(target_name="A") + class TestFeatures: def test_should_return_features(self, tagged_table: TaggedTable) -> None: diff --git a/tests/safeds/data/tabular/typing/_table_schema/test_get_column_type.py b/tests/safeds/data/tabular/typing/_table_schema/test_get_column_type.py index 110f0432d..e15837deb 100644 --- a/tests/safeds/data/tabular/typing/_table_schema/test_get_column_type.py +++ b/tests/safeds/data/tabular/typing/_table_schema/test_get_column_type.py @@ -1,7 +1,7 @@ import numpy as np from safeds.data.tabular.containers import Table from safeds.data.tabular.typing import ColumnType -from tests.fixtures import resolve_resource_path +from tests.helpers import resolve_resource_path def test_get_type_of_column() -> None: diff --git a/tests/safeds/data/tabular/typing/_table_schema/test_has_column.py b/tests/safeds/data/tabular/typing/_table_schema/test_has_column.py index 5a3329d94..6ad02eb47 100644 --- a/tests/safeds/data/tabular/typing/_table_schema/test_has_column.py +++ b/tests/safeds/data/tabular/typing/_table_schema/test_has_column.py @@ -1,5 +1,5 @@ from safeds.data.tabular.containers import Table -from tests.fixtures import resolve_resource_path +from tests.helpers import resolve_resource_path def test_has_column_true() -> None: diff --git a/tests/safeds/data/tabular/typing/_table_schema/test_table_equals.py b/tests/safeds/data/tabular/typing/_table_schema/test_table_equals.py index 715e03567..f1dc9c080 100644 --- a/tests/safeds/data/tabular/typing/_table_schema/test_table_equals.py +++ b/tests/safeds/data/tabular/typing/_table_schema/test_table_equals.py @@ -1,6 +1,6 @@ from safeds.data.tabular.containers import Table from safeds.data.tabular.typing import FloatColumnType, IntColumnType, TableSchema -from tests.fixtures import resolve_resource_path +from tests.helpers import resolve_resource_path def test_table_equals_valid() -> None: diff --git a/tests/safeds/ml/classification/test_ada_boost.py b/tests/safeds/ml/classification/test_ada_boost.py index f874b4767..8050a868b 100644 --- a/tests/safeds/ml/classification/test_ada_boost.py +++ b/tests/safeds/ml/classification/test_ada_boost.py @@ -1,8 +1,8 @@ import pytest -from safeds.data.tabular.containers import Table, TaggedTable +from safeds.data.tabular.containers import Table, TaggedTable, Column from safeds.exceptions import LearningError, PredictionError from safeds.ml.classification import AdaBoost, Classifier -from tests.fixtures import resolve_resource_path +from tests.helpers import resolve_resource_path @pytest.fixture() @@ -12,14 +12,26 @@ def classifier() -> Classifier: @pytest.fixture() def valid_data() -> TaggedTable: - table = Table.from_csv_file(resolve_resource_path("test_ada_boost.csv")) - return table.tag_columns(target_name="T") + return Table.from_columns( + [ + Column("id", [1, 4]), + Column("feat1", [2, 5]), + Column("feat2", [3, 6]), + Column("target", [0, 1]), + ] + ).tag_columns(target_name="target", feature_names=["feat1", "feat2"]) @pytest.fixture() def invalid_data() -> TaggedTable: - table = Table.from_csv_file(resolve_resource_path("test_ada_boost_invalid.csv")) - return table.tag_columns(target_name="T") + return Table.from_columns( + [ + Column("id", [1, 4]), + Column("feat1", ["a", 5]), + Column("feat2", [3, 6]), + Column("target", [0, 1]), + ] + ).tag_columns(target_name="target", feature_names=["feat1", "feat2"]) class TestFit: @@ -41,7 +53,7 @@ def test_should_include_features_of_prediction_input(self, classifier: Classifie def test_should_set_correct_target_name(self, classifier: Classifier, valid_data: TaggedTable) -> None: fitted_classifier = classifier.fit(valid_data) prediction = fitted_classifier.predict(valid_data.features) - assert prediction.target.name == "T" + assert prediction.target.name == "target" def test_should_raise_when_not_fitted(self, classifier: Classifier, valid_data: TaggedTable) -> None: with pytest.raises(PredictionError): diff --git a/tests/safeds/ml/classification/test_decision_tree.py b/tests/safeds/ml/classification/test_decision_tree.py index 42fb26858..3a8389d80 100644 --- a/tests/safeds/ml/classification/test_decision_tree.py +++ b/tests/safeds/ml/classification/test_decision_tree.py @@ -2,7 +2,7 @@ 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 +from tests.helpers import resolve_resource_path @pytest.fixture() diff --git a/tests/safeds/ml/classification/test_gradient_boosting.py b/tests/safeds/ml/classification/test_gradient_boosting.py index b24228a9d..6a475a0e8 100644 --- a/tests/safeds/ml/classification/test_gradient_boosting.py +++ b/tests/safeds/ml/classification/test_gradient_boosting.py @@ -2,7 +2,7 @@ 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 +from tests.helpers import resolve_resource_path @pytest.fixture() diff --git a/tests/safeds/ml/classification/test_k_nearest_neighbors.py b/tests/safeds/ml/classification/test_k_nearest_neighbors.py index bb6f68b1e..469829f4b 100644 --- a/tests/safeds/ml/classification/test_k_nearest_neighbors.py +++ b/tests/safeds/ml/classification/test_k_nearest_neighbors.py @@ -2,7 +2,7 @@ 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 +from tests.helpers import resolve_resource_path @pytest.fixture() diff --git a/tests/safeds/ml/classification/test_logistic_regression.py b/tests/safeds/ml/classification/test_logistic_regression.py index 5dbaa5960..67b4f7d19 100644 --- a/tests/safeds/ml/classification/test_logistic_regression.py +++ b/tests/safeds/ml/classification/test_logistic_regression.py @@ -2,7 +2,7 @@ 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 +from tests.helpers import resolve_resource_path @pytest.fixture() diff --git a/tests/safeds/ml/classification/test_random_forest.py b/tests/safeds/ml/classification/test_random_forest.py index 266d39f0d..2289a6638 100644 --- a/tests/safeds/ml/classification/test_random_forest.py +++ b/tests/safeds/ml/classification/test_random_forest.py @@ -2,7 +2,7 @@ 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 +from tests.helpers import resolve_resource_path @pytest.fixture() diff --git a/tests/safeds/ml/regression/test_ada_boost.py b/tests/safeds/ml/regression/test_ada_boost.py index db2e15d18..3acbc0027 100644 --- a/tests/safeds/ml/regression/test_ada_boost.py +++ b/tests/safeds/ml/regression/test_ada_boost.py @@ -1,8 +1,8 @@ import pytest -from safeds.data.tabular.containers import Table, TaggedTable + +from safeds.data.tabular.containers import Table, TaggedTable, Column from safeds.exceptions import LearningError, PredictionError from safeds.ml.regression import AdaBoost, Regressor -from tests.fixtures import resolve_resource_path @pytest.fixture() @@ -12,14 +12,26 @@ def regressor() -> Regressor: @pytest.fixture() def valid_data() -> TaggedTable: - table = Table.from_csv_file(resolve_resource_path("test_ada_boost.csv")) - return table.tag_columns(target_name="T") + return Table.from_columns( + [ + Column("id", [1, 4]), + Column("feat1", [2, 5]), + Column("feat2", [3, 6]), + Column("target", [0, 1]), + ] + ).tag_columns(target_name="target", feature_names=["feat1", "feat2"]) @pytest.fixture() def invalid_data() -> TaggedTable: - table = Table.from_csv_file(resolve_resource_path("test_ada_boost_invalid.csv")) - return table.tag_columns(target_name="T") + return Table.from_columns( + [ + Column("id", [1, 4]), + Column("feat1", ["a", 5]), + Column("feat2", [3, 6]), + Column("target", [0, 1]), + ] + ).tag_columns(target_name="target", feature_names=["feat1", "feat2"]) class TestFit: @@ -41,7 +53,15 @@ def test_should_include_features_of_prediction_input(self, regressor: Regressor, def test_should_set_correct_target_name(self, regressor: Regressor, valid_data: TaggedTable) -> None: fitted_regressor = regressor.fit(valid_data) prediction = fitted_regressor.predict(valid_data.features) - assert prediction.target.name == "T" + assert prediction.target.name == "target" + + def test_should_include_other_columns_of_prediction_input(self, regressor: Regressor, valid_data: TaggedTable) -> None: + fitted_regressor = regressor.fit(valid_data) + prediction = fitted_regressor.predict(valid_data.drop_columns(["target"])) + other_column_names = list( + set(valid_data.get_column_names()) - set(valid_data.features.get_column_names()) - {valid_data.target.name} + ) + assert prediction.keep_only_columns(other_column_names) == valid_data.keep_only_columns(other_column_names) def test_should_raise_when_not_fitted(self, regressor: Regressor, valid_data: TaggedTable) -> None: with pytest.raises(PredictionError): diff --git a/tests/safeds/ml/regression/test_decision_tree.py b/tests/safeds/ml/regression/test_decision_tree.py index 13537681d..78630abfa 100644 --- a/tests/safeds/ml/regression/test_decision_tree.py +++ b/tests/safeds/ml/regression/test_decision_tree.py @@ -2,7 +2,7 @@ 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 +from tests.helpers import resolve_resource_path @pytest.fixture() diff --git a/tests/safeds/ml/regression/test_elastic_net.py b/tests/safeds/ml/regression/test_elastic_net.py index 9d4da822a..a788c07dc 100644 --- a/tests/safeds/ml/regression/test_elastic_net.py +++ b/tests/safeds/ml/regression/test_elastic_net.py @@ -2,7 +2,7 @@ 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 +from tests.helpers import resolve_resource_path @pytest.fixture() diff --git a/tests/safeds/ml/regression/test_gradient_boosting.py b/tests/safeds/ml/regression/test_gradient_boosting.py index b432cc185..f4970cd99 100644 --- a/tests/safeds/ml/regression/test_gradient_boosting.py +++ b/tests/safeds/ml/regression/test_gradient_boosting.py @@ -2,7 +2,7 @@ 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 +from tests.helpers import resolve_resource_path @pytest.fixture() diff --git a/tests/safeds/ml/regression/test_k_nearest_neighbors.py b/tests/safeds/ml/regression/test_k_nearest_neighbors.py index f68ea803d..0b1b9eeec 100644 --- a/tests/safeds/ml/regression/test_k_nearest_neighbors.py +++ b/tests/safeds/ml/regression/test_k_nearest_neighbors.py @@ -2,7 +2,7 @@ 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 +from tests.helpers import resolve_resource_path @pytest.fixture() diff --git a/tests/safeds/ml/regression/test_lasso_regression.py b/tests/safeds/ml/regression/test_lasso_regression.py index 3f49f111e..c008a68ac 100644 --- a/tests/safeds/ml/regression/test_lasso_regression.py +++ b/tests/safeds/ml/regression/test_lasso_regression.py @@ -2,7 +2,7 @@ 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 +from tests.helpers import resolve_resource_path @pytest.fixture() diff --git a/tests/safeds/ml/regression/test_linear_regression.py b/tests/safeds/ml/regression/test_linear_regression.py index d5e705dfc..58cc3fe58 100644 --- a/tests/safeds/ml/regression/test_linear_regression.py +++ b/tests/safeds/ml/regression/test_linear_regression.py @@ -2,7 +2,7 @@ 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 +from tests.helpers import resolve_resource_path @pytest.fixture() diff --git a/tests/safeds/ml/regression/test_random_forest.py b/tests/safeds/ml/regression/test_random_forest.py index 3f63878fe..235fee023 100644 --- a/tests/safeds/ml/regression/test_random_forest.py +++ b/tests/safeds/ml/regression/test_random_forest.py @@ -2,7 +2,7 @@ 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 +from tests.helpers import resolve_resource_path @pytest.fixture() diff --git a/tests/safeds/ml/regression/test_ridge_regression.py b/tests/safeds/ml/regression/test_ridge_regression.py index f5ff7a93d..321a9f147 100644 --- a/tests/safeds/ml/regression/test_ridge_regression.py +++ b/tests/safeds/ml/regression/test_ridge_regression.py @@ -2,7 +2,7 @@ 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 +from tests.helpers import resolve_resource_path @pytest.fixture() diff --git a/tests/safeds/ml/test_util_sklearn.py b/tests/safeds/ml/test_util_sklearn.py index c9fab0824..85913417a 100644 --- a/tests/safeds/ml/test_util_sklearn.py +++ b/tests/safeds/ml/test_util_sklearn.py @@ -19,4 +19,4 @@ def test_predict_should_not_warn_about_feature_names() -> None: # No warning should be emitted with warnings.catch_warnings(): warnings.filterwarnings("error", message="X has feature names") - fitted_model.predict(dataset=test_set) + fitted_model.predict(test_set) From d0ab0a11cefe927e5574257eb74982cb554658fc Mon Sep 17 00:00:00 2001 From: Lars Reimann Date: Wed, 29 Mar 2023 21:21:30 +0200 Subject: [PATCH 09/14] fix: set column names in DataFrame --- src/safeds/ml/_util_sklearn.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/safeds/ml/_util_sklearn.py b/src/safeds/ml/_util_sklearn.py index 9d11c928d..28435b726 100644 --- a/src/safeds/ml/_util_sklearn.py +++ b/src/safeds/ml/_util_sklearn.py @@ -66,6 +66,7 @@ def predict(model: Any, dataset: Table, feature_names: Optional[list[str]], targ try: predicted_target_vector = model.predict(dataset_df.values) result_set = dataset._data.copy(deep=True) + result_set.columns = dataset.get_column_names() if target_name in result_set.columns: raise ValueError(f"Dataset already contains '{target_name}' column. Please rename this column") result_set[target_name] = predicted_target_vector From c2edf88e555fe24a32d10cfc7c29019543d67e67 Mon Sep 17 00:00:00 2001 From: Lars Reimann Date: Wed, 29 Mar 2023 21:29:34 +0200 Subject: [PATCH 10/14] style: fix linter errors --- tests/safeds/ml/classification/test_ada_boost.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/safeds/ml/classification/test_ada_boost.py b/tests/safeds/ml/classification/test_ada_boost.py index 8050a868b..b7f2fe45e 100644 --- a/tests/safeds/ml/classification/test_ada_boost.py +++ b/tests/safeds/ml/classification/test_ada_boost.py @@ -1,8 +1,8 @@ import pytest + from safeds.data.tabular.containers import Table, TaggedTable, Column from safeds.exceptions import LearningError, PredictionError from safeds.ml.classification import AdaBoost, Classifier -from tests.helpers import resolve_resource_path @pytest.fixture() From 9e7b7febcd894ec7d38c12f6efb9730b292bee13 Mon Sep 17 00:00:00 2001 From: Lars Reimann Date: Wed, 29 Mar 2023 21:39:12 +0200 Subject: [PATCH 11/14] test: integrate data into test files --- tests/resources/test_decision_tree.csv | 3 --- .../resources/test_decision_tree_invalid.csv | 3 --- .../resources/test_elastic_net_regression.csv | 3 --- .../test_elastic_net_regression_invalid.csv | 3 --- .../test_gradient_boosting_classification.csv | 3 --- ...adient_boosting_classification_invalid.csv | 3 --- .../test_gradient_boosting_regression.csv | 3 --- ...t_gradient_boosting_regression_invalid.csv | 3 --- tests/resources/test_k_nearest_neighbors.csv | 3 --- .../test_k_nearest_neighbors_invalid.csv | 3 --- tests/resources/test_lasso_regression.csv | 3 --- .../test_lasso_regression_invalid.csv | 3 --- tests/resources/test_linear_regression.csv | 3 --- .../test_linear_regression_invalid.csv | 3 --- tests/resources/test_logistic_regression.csv | 3 --- .../test_logistic_regression_invalid.csv | 3 --- tests/resources/test_random_forest.csv | 3 --- .../resources/test_random_forest_invalid.csv | 3 --- tests/resources/test_ridge_regression.csv | 3 --- .../test_ridge_regression_invalid.csv | 3 --- .../ml/classification/test_classifier.py | 1 + .../ml/classification/test_decision_tree.py | 26 ++++++++++++++----- .../classification/test_gradient_boosting.py | 26 ++++++++++++++----- .../test_k_nearest_neighbors.py | 25 +++++++++++++----- .../test_logistic_regression.py | 26 ++++++++++++++----- .../ml/classification/test_random_forest.py | 26 ++++++++++++++----- .../ml/regression/test_decision_tree.py | 26 ++++++++++++++----- .../safeds/ml/regression/test_elastic_net.py | 26 ++++++++++++++----- .../ml/regression/test_gradient_boosting.py | 26 ++++++++++++++----- .../ml/regression/test_k_nearest_neighbors.py | 26 ++++++++++++++----- .../ml/regression/test_lasso_regression.py | 26 ++++++++++++++----- .../ml/regression/test_linear_regression.py | 26 ++++++++++++++----- .../ml/regression/test_random_forest.py | 26 ++++++++++++++----- tests/safeds/ml/regression/test_regressor.py | 2 +- .../ml/regression/test_ridge_regression.py | 26 ++++++++++++++----- 35 files changed, 249 insertions(+), 151 deletions(-) delete mode 100644 tests/resources/test_decision_tree.csv delete mode 100644 tests/resources/test_decision_tree_invalid.csv delete mode 100644 tests/resources/test_elastic_net_regression.csv delete mode 100644 tests/resources/test_elastic_net_regression_invalid.csv delete mode 100644 tests/resources/test_gradient_boosting_classification.csv delete mode 100644 tests/resources/test_gradient_boosting_classification_invalid.csv delete mode 100644 tests/resources/test_gradient_boosting_regression.csv delete mode 100644 tests/resources/test_gradient_boosting_regression_invalid.csv delete mode 100644 tests/resources/test_k_nearest_neighbors.csv delete mode 100644 tests/resources/test_k_nearest_neighbors_invalid.csv delete mode 100644 tests/resources/test_lasso_regression.csv delete mode 100644 tests/resources/test_lasso_regression_invalid.csv delete mode 100644 tests/resources/test_linear_regression.csv delete mode 100644 tests/resources/test_linear_regression_invalid.csv delete mode 100644 tests/resources/test_logistic_regression.csv delete mode 100644 tests/resources/test_logistic_regression_invalid.csv delete mode 100644 tests/resources/test_random_forest.csv delete mode 100644 tests/resources/test_random_forest_invalid.csv delete mode 100644 tests/resources/test_ridge_regression.csv delete mode 100644 tests/resources/test_ridge_regression_invalid.csv diff --git a/tests/resources/test_decision_tree.csv b/tests/resources/test_decision_tree.csv deleted file mode 100644 index 5ba8f4fad..000000000 --- a/tests/resources/test_decision_tree.csv +++ /dev/null @@ -1,3 +0,0 @@ -A,B,C,T -1,2,3,0 -4,5,6,1 diff --git a/tests/resources/test_decision_tree_invalid.csv b/tests/resources/test_decision_tree_invalid.csv deleted file mode 100644 index cfcf7131d..000000000 --- a/tests/resources/test_decision_tree_invalid.csv +++ /dev/null @@ -1,3 +0,0 @@ -A,B,C,T -A,2,3,0 -4,5,6,1 diff --git a/tests/resources/test_elastic_net_regression.csv b/tests/resources/test_elastic_net_regression.csv deleted file mode 100644 index 5ba8f4fad..000000000 --- a/tests/resources/test_elastic_net_regression.csv +++ /dev/null @@ -1,3 +0,0 @@ -A,B,C,T -1,2,3,0 -4,5,6,1 diff --git a/tests/resources/test_elastic_net_regression_invalid.csv b/tests/resources/test_elastic_net_regression_invalid.csv deleted file mode 100644 index cfcf7131d..000000000 --- a/tests/resources/test_elastic_net_regression_invalid.csv +++ /dev/null @@ -1,3 +0,0 @@ -A,B,C,T -A,2,3,0 -4,5,6,1 diff --git a/tests/resources/test_gradient_boosting_classification.csv b/tests/resources/test_gradient_boosting_classification.csv deleted file mode 100644 index 5ba8f4fad..000000000 --- a/tests/resources/test_gradient_boosting_classification.csv +++ /dev/null @@ -1,3 +0,0 @@ -A,B,C,T -1,2,3,0 -4,5,6,1 diff --git a/tests/resources/test_gradient_boosting_classification_invalid.csv b/tests/resources/test_gradient_boosting_classification_invalid.csv deleted file mode 100644 index cfcf7131d..000000000 --- a/tests/resources/test_gradient_boosting_classification_invalid.csv +++ /dev/null @@ -1,3 +0,0 @@ -A,B,C,T -A,2,3,0 -4,5,6,1 diff --git a/tests/resources/test_gradient_boosting_regression.csv b/tests/resources/test_gradient_boosting_regression.csv deleted file mode 100644 index 5ba8f4fad..000000000 --- a/tests/resources/test_gradient_boosting_regression.csv +++ /dev/null @@ -1,3 +0,0 @@ -A,B,C,T -1,2,3,0 -4,5,6,1 diff --git a/tests/resources/test_gradient_boosting_regression_invalid.csv b/tests/resources/test_gradient_boosting_regression_invalid.csv deleted file mode 100644 index cfcf7131d..000000000 --- a/tests/resources/test_gradient_boosting_regression_invalid.csv +++ /dev/null @@ -1,3 +0,0 @@ -A,B,C,T -A,2,3,0 -4,5,6,1 diff --git a/tests/resources/test_k_nearest_neighbors.csv b/tests/resources/test_k_nearest_neighbors.csv deleted file mode 100644 index 5ba8f4fad..000000000 --- a/tests/resources/test_k_nearest_neighbors.csv +++ /dev/null @@ -1,3 +0,0 @@ -A,B,C,T -1,2,3,0 -4,5,6,1 diff --git a/tests/resources/test_k_nearest_neighbors_invalid.csv b/tests/resources/test_k_nearest_neighbors_invalid.csv deleted file mode 100644 index cfcf7131d..000000000 --- a/tests/resources/test_k_nearest_neighbors_invalid.csv +++ /dev/null @@ -1,3 +0,0 @@ -A,B,C,T -A,2,3,0 -4,5,6,1 diff --git a/tests/resources/test_lasso_regression.csv b/tests/resources/test_lasso_regression.csv deleted file mode 100644 index 5ba8f4fad..000000000 --- a/tests/resources/test_lasso_regression.csv +++ /dev/null @@ -1,3 +0,0 @@ -A,B,C,T -1,2,3,0 -4,5,6,1 diff --git a/tests/resources/test_lasso_regression_invalid.csv b/tests/resources/test_lasso_regression_invalid.csv deleted file mode 100644 index cfcf7131d..000000000 --- a/tests/resources/test_lasso_regression_invalid.csv +++ /dev/null @@ -1,3 +0,0 @@ -A,B,C,T -A,2,3,0 -4,5,6,1 diff --git a/tests/resources/test_linear_regression.csv b/tests/resources/test_linear_regression.csv deleted file mode 100644 index 5ba8f4fad..000000000 --- a/tests/resources/test_linear_regression.csv +++ /dev/null @@ -1,3 +0,0 @@ -A,B,C,T -1,2,3,0 -4,5,6,1 diff --git a/tests/resources/test_linear_regression_invalid.csv b/tests/resources/test_linear_regression_invalid.csv deleted file mode 100644 index cfcf7131d..000000000 --- a/tests/resources/test_linear_regression_invalid.csv +++ /dev/null @@ -1,3 +0,0 @@ -A,B,C,T -A,2,3,0 -4,5,6,1 diff --git a/tests/resources/test_logistic_regression.csv b/tests/resources/test_logistic_regression.csv deleted file mode 100644 index 5ba8f4fad..000000000 --- a/tests/resources/test_logistic_regression.csv +++ /dev/null @@ -1,3 +0,0 @@ -A,B,C,T -1,2,3,0 -4,5,6,1 diff --git a/tests/resources/test_logistic_regression_invalid.csv b/tests/resources/test_logistic_regression_invalid.csv deleted file mode 100644 index cfcf7131d..000000000 --- a/tests/resources/test_logistic_regression_invalid.csv +++ /dev/null @@ -1,3 +0,0 @@ -A,B,C,T -A,2,3,0 -4,5,6,1 diff --git a/tests/resources/test_random_forest.csv b/tests/resources/test_random_forest.csv deleted file mode 100644 index 5ba8f4fad..000000000 --- a/tests/resources/test_random_forest.csv +++ /dev/null @@ -1,3 +0,0 @@ -A,B,C,T -1,2,3,0 -4,5,6,1 diff --git a/tests/resources/test_random_forest_invalid.csv b/tests/resources/test_random_forest_invalid.csv deleted file mode 100644 index cfcf7131d..000000000 --- a/tests/resources/test_random_forest_invalid.csv +++ /dev/null @@ -1,3 +0,0 @@ -A,B,C,T -A,2,3,0 -4,5,6,1 diff --git a/tests/resources/test_ridge_regression.csv b/tests/resources/test_ridge_regression.csv deleted file mode 100644 index 5ba8f4fad..000000000 --- a/tests/resources/test_ridge_regression.csv +++ /dev/null @@ -1,3 +0,0 @@ -A,B,C,T -1,2,3,0 -4,5,6,1 diff --git a/tests/resources/test_ridge_regression_invalid.csv b/tests/resources/test_ridge_regression_invalid.csv deleted file mode 100644 index cfcf7131d..000000000 --- a/tests/resources/test_ridge_regression_invalid.csv +++ /dev/null @@ -1,3 +0,0 @@ -A,B,C,T -A,2,3,0 -4,5,6,1 diff --git a/tests/safeds/ml/classification/test_classifier.py b/tests/safeds/ml/classification/test_classifier.py index be48ab662..4bc6a76e6 100644 --- a/tests/safeds/ml/classification/test_classifier.py +++ b/tests/safeds/ml/classification/test_classifier.py @@ -1,6 +1,7 @@ from __future__ import annotations import pandas as pd + from safeds.data.tabular.containers import Column, Table, TaggedTable from safeds.ml.classification import Classifier diff --git a/tests/safeds/ml/classification/test_decision_tree.py b/tests/safeds/ml/classification/test_decision_tree.py index 3a8389d80..9b3e8065a 100644 --- a/tests/safeds/ml/classification/test_decision_tree.py +++ b/tests/safeds/ml/classification/test_decision_tree.py @@ -1,8 +1,8 @@ import pytest -from safeds.data.tabular.containers import Table, TaggedTable + +from safeds.data.tabular.containers import Table, TaggedTable, Column from safeds.exceptions import LearningError, PredictionError from safeds.ml.classification import Classifier, DecisionTree -from tests.helpers import resolve_resource_path @pytest.fixture() @@ -12,14 +12,26 @@ def classifier() -> Classifier: @pytest.fixture() def valid_data() -> TaggedTable: - table = Table.from_csv_file(resolve_resource_path("test_decision_tree.csv")) - return table.tag_columns(target_name="T") + return Table.from_columns( + [ + Column("id", [1, 4]), + Column("feat1", [2, 5]), + Column("feat2", [3, 6]), + Column("target", [0, 1]), + ] + ).tag_columns(target_name="target", feature_names=["feat1", "feat2"]) @pytest.fixture() def invalid_data() -> TaggedTable: - table = Table.from_csv_file(resolve_resource_path("test_decision_tree_invalid.csv")) - return table.tag_columns(target_name="T") + return Table.from_columns( + [ + Column("id", [1, 4]), + Column("feat1", ["a", 5]), + Column("feat2", [3, 6]), + Column("target", [0, 1]), + ] + ).tag_columns(target_name="target", feature_names=["feat1", "feat2"]) class TestFit: @@ -41,7 +53,7 @@ def test_should_include_features_of_prediction_input(self, classifier: Classifie def test_should_set_correct_target_name(self, classifier: Classifier, valid_data: TaggedTable) -> None: fitted_classifier = classifier.fit(valid_data) prediction = fitted_classifier.predict(valid_data.features) - assert prediction.target.name == "T" + assert prediction.target.name == "target" def test_should_raise_when_not_fitted(self, classifier: Classifier, valid_data: TaggedTable) -> None: with pytest.raises(PredictionError): diff --git a/tests/safeds/ml/classification/test_gradient_boosting.py b/tests/safeds/ml/classification/test_gradient_boosting.py index 6a475a0e8..417f4574d 100644 --- a/tests/safeds/ml/classification/test_gradient_boosting.py +++ b/tests/safeds/ml/classification/test_gradient_boosting.py @@ -1,8 +1,8 @@ import pytest -from safeds.data.tabular.containers import Table, TaggedTable + +from safeds.data.tabular.containers import Table, TaggedTable, Column from safeds.exceptions import LearningError, PredictionError from safeds.ml.classification import Classifier, GradientBoosting -from tests.helpers import resolve_resource_path @pytest.fixture() @@ -12,14 +12,26 @@ def classifier() -> Classifier: @pytest.fixture() def valid_data() -> TaggedTable: - table = Table.from_csv_file(resolve_resource_path("test_gradient_boosting_classification.csv")) - return table.tag_columns(target_name="T") + return Table.from_columns( + [ + Column("id", [1, 4]), + Column("feat1", [2, 5]), + Column("feat2", [3, 6]), + Column("target", [0, 1]), + ] + ).tag_columns(target_name="target", feature_names=["feat1", "feat2"]) @pytest.fixture() def invalid_data() -> TaggedTable: - table = Table.from_csv_file(resolve_resource_path("test_gradient_boosting_classification_invalid.csv")) - return table.tag_columns(target_name="T") + return Table.from_columns( + [ + Column("id", [1, 4]), + Column("feat1", ["a", 5]), + Column("feat2", [3, 6]), + Column("target", [0, 1]), + ] + ).tag_columns(target_name="target", feature_names=["feat1", "feat2"]) class TestFit: @@ -41,7 +53,7 @@ def test_should_include_features_of_prediction_input(self, classifier: Classifie def test_should_set_correct_target_name(self, classifier: Classifier, valid_data: TaggedTable) -> None: fitted_classifier = classifier.fit(valid_data) prediction = fitted_classifier.predict(valid_data.features) - assert prediction.target.name == "T" + assert prediction.target.name == "target" def test_should_raise_when_not_fitted(self, classifier: Classifier, valid_data: TaggedTable) -> None: with pytest.raises(PredictionError): diff --git a/tests/safeds/ml/classification/test_k_nearest_neighbors.py b/tests/safeds/ml/classification/test_k_nearest_neighbors.py index 469829f4b..ff1cf3b38 100644 --- a/tests/safeds/ml/classification/test_k_nearest_neighbors.py +++ b/tests/safeds/ml/classification/test_k_nearest_neighbors.py @@ -1,5 +1,6 @@ import pytest -from safeds.data.tabular.containers import Table, TaggedTable + +from safeds.data.tabular.containers import Table, TaggedTable, Column from safeds.exceptions import LearningError, PredictionError from safeds.ml.classification import Classifier, KNearestNeighbors from tests.helpers import resolve_resource_path @@ -12,14 +13,26 @@ def classifier() -> Classifier: @pytest.fixture() def valid_data() -> TaggedTable: - table = Table.from_csv_file(resolve_resource_path("test_k_nearest_neighbors.csv")) - return table.tag_columns(target_name="T") + return Table.from_columns( + [ + Column("id", [1, 4]), + Column("feat1", [2, 5]), + Column("feat2", [3, 6]), + Column("target", [0, 1]), + ] + ).tag_columns(target_name="target", feature_names=["feat1", "feat2"]) @pytest.fixture() def invalid_data() -> TaggedTable: - table = Table.from_csv_file(resolve_resource_path("test_k_nearest_neighbors_invalid.csv")) - return table.tag_columns(target_name="T") + return Table.from_columns( + [ + Column("id", [1, 4]), + Column("feat1", ["a", 5]), + Column("feat2", [3, 6]), + Column("target", [0, 1]), + ] + ).tag_columns(target_name="target", feature_names=["feat1", "feat2"]) class TestFit: @@ -41,7 +54,7 @@ def test_should_include_features_of_prediction_input(self, classifier: Classifie def test_should_set_correct_target_name(self, classifier: Classifier, valid_data: TaggedTable) -> None: fitted_classifier = classifier.fit(valid_data) prediction = fitted_classifier.predict(valid_data.features) - assert prediction.target.name == "T" + assert prediction.target.name == "target" def test_should_raise_when_not_fitted(self, classifier: Classifier, valid_data: TaggedTable) -> None: with pytest.raises(PredictionError): diff --git a/tests/safeds/ml/classification/test_logistic_regression.py b/tests/safeds/ml/classification/test_logistic_regression.py index 67b4f7d19..0e0419451 100644 --- a/tests/safeds/ml/classification/test_logistic_regression.py +++ b/tests/safeds/ml/classification/test_logistic_regression.py @@ -1,8 +1,8 @@ import pytest -from safeds.data.tabular.containers import Table, TaggedTable + +from safeds.data.tabular.containers import Table, TaggedTable, Column from safeds.exceptions import LearningError, PredictionError from safeds.ml.classification import Classifier, LogisticRegression -from tests.helpers import resolve_resource_path @pytest.fixture() @@ -12,14 +12,26 @@ def classifier() -> Classifier: @pytest.fixture() def valid_data() -> TaggedTable: - table = Table.from_csv_file(resolve_resource_path("test_logistic_regression.csv")) - return table.tag_columns(target_name="T") + return Table.from_columns( + [ + Column("id", [1, 4]), + Column("feat1", [2, 5]), + Column("feat2", [3, 6]), + Column("target", [0, 1]), + ] + ).tag_columns(target_name="target", feature_names=["feat1", "feat2"]) @pytest.fixture() def invalid_data() -> TaggedTable: - table = Table.from_csv_file(resolve_resource_path("test_logistic_regression_invalid.csv")) - return table.tag_columns(target_name="T") + return Table.from_columns( + [ + Column("id", [1, 4]), + Column("feat1", ["a", 5]), + Column("feat2", [3, 6]), + Column("target", [0, 1]), + ] + ).tag_columns(target_name="target", feature_names=["feat1", "feat2"]) class TestFit: @@ -41,7 +53,7 @@ def test_should_include_features_of_prediction_input(self, classifier: Classifie def test_should_set_correct_target_name(self, classifier: Classifier, valid_data: TaggedTable) -> None: fitted_classifier = classifier.fit(valid_data) prediction = fitted_classifier.predict(valid_data.features) - assert prediction.target.name == "T" + assert prediction.target.name == "target" def test_should_raise_when_not_fitted(self, classifier: Classifier, valid_data: TaggedTable) -> None: with pytest.raises(PredictionError): diff --git a/tests/safeds/ml/classification/test_random_forest.py b/tests/safeds/ml/classification/test_random_forest.py index 2289a6638..d56f4d119 100644 --- a/tests/safeds/ml/classification/test_random_forest.py +++ b/tests/safeds/ml/classification/test_random_forest.py @@ -1,8 +1,8 @@ import pytest -from safeds.data.tabular.containers import Table, TaggedTable + +from safeds.data.tabular.containers import Table, TaggedTable, Column from safeds.exceptions import LearningError, PredictionError from safeds.ml.classification import Classifier, RandomForest -from tests.helpers import resolve_resource_path @pytest.fixture() @@ -12,14 +12,26 @@ def classifier() -> Classifier: @pytest.fixture() def valid_data() -> TaggedTable: - table = Table.from_csv_file(resolve_resource_path("test_random_forest.csv")) - return table.tag_columns(target_name="T") + return Table.from_columns( + [ + Column("id", [1, 4]), + Column("feat1", [2, 5]), + Column("feat2", [3, 6]), + Column("target", [0, 1]), + ] + ).tag_columns(target_name="target", feature_names=["feat1", "feat2"]) @pytest.fixture() def invalid_data() -> TaggedTable: - table = Table.from_csv_file(resolve_resource_path("test_random_forest_invalid.csv")) - return table.tag_columns(target_name="T") + return Table.from_columns( + [ + Column("id", [1, 4]), + Column("feat1", ["a", 5]), + Column("feat2", [3, 6]), + Column("target", [0, 1]), + ] + ).tag_columns(target_name="target", feature_names=["feat1", "feat2"]) class TestFit: @@ -41,7 +53,7 @@ def test_should_include_features_of_prediction_input(self, classifier: Classifie def test_should_set_correct_target_name(self, classifier: Classifier, valid_data: TaggedTable) -> None: fitted_classifier = classifier.fit(valid_data) prediction = fitted_classifier.predict(valid_data.features) - assert prediction.target.name == "T" + assert prediction.target.name == "target" def test_should_raise_when_not_fitted(self, classifier: Classifier, valid_data: TaggedTable) -> None: with pytest.raises(PredictionError): diff --git a/tests/safeds/ml/regression/test_decision_tree.py b/tests/safeds/ml/regression/test_decision_tree.py index 78630abfa..f9856bfd9 100644 --- a/tests/safeds/ml/regression/test_decision_tree.py +++ b/tests/safeds/ml/regression/test_decision_tree.py @@ -1,8 +1,8 @@ import pytest -from safeds.data.tabular.containers import Table, TaggedTable + +from safeds.data.tabular.containers import Table, TaggedTable, Column from safeds.exceptions import LearningError, PredictionError from safeds.ml.regression import DecisionTree, Regressor -from tests.helpers import resolve_resource_path @pytest.fixture() @@ -12,14 +12,26 @@ def regressor() -> Regressor: @pytest.fixture() def valid_data() -> TaggedTable: - table = Table.from_csv_file(resolve_resource_path("test_decision_tree.csv")) - return table.tag_columns(target_name="T") + return Table.from_columns( + [ + Column("id", [1, 4]), + Column("feat1", [2, 5]), + Column("feat2", [3, 6]), + Column("target", [0, 1]), + ] + ).tag_columns(target_name="target", feature_names=["feat1", "feat2"]) @pytest.fixture() def invalid_data() -> TaggedTable: - table = Table.from_csv_file(resolve_resource_path("test_decision_tree_invalid.csv")) - return table.tag_columns(target_name="T") + return Table.from_columns( + [ + Column("id", [1, 4]), + Column("feat1", ["a", 5]), + Column("feat2", [3, 6]), + Column("target", [0, 1]), + ] + ).tag_columns(target_name="target", feature_names=["feat1", "feat2"]) class TestFit: @@ -41,7 +53,7 @@ def test_should_include_features_of_prediction_input(self, regressor: Regressor, def test_should_set_correct_target_name(self, regressor: Regressor, valid_data: TaggedTable) -> None: fitted_regressor = regressor.fit(valid_data) prediction = fitted_regressor.predict(valid_data.features) - assert prediction.target.name == "T" + assert prediction.target.name == "target" def test_should_raise_when_not_fitted(self, regressor: Regressor, valid_data: TaggedTable) -> None: with pytest.raises(PredictionError): diff --git a/tests/safeds/ml/regression/test_elastic_net.py b/tests/safeds/ml/regression/test_elastic_net.py index a788c07dc..ded342ffe 100644 --- a/tests/safeds/ml/regression/test_elastic_net.py +++ b/tests/safeds/ml/regression/test_elastic_net.py @@ -1,8 +1,8 @@ import pytest -from safeds.data.tabular.containers import Table, TaggedTable + +from safeds.data.tabular.containers import Table, TaggedTable, Column from safeds.exceptions import LearningError, PredictionError from safeds.ml.regression import ElasticNetRegression, Regressor -from tests.helpers import resolve_resource_path @pytest.fixture() @@ -12,14 +12,26 @@ def regressor() -> Regressor: @pytest.fixture() def valid_data() -> TaggedTable: - table = Table.from_csv_file(resolve_resource_path("test_elastic_net_regression.csv")) - return table.tag_columns(target_name="T") + return Table.from_columns( + [ + Column("id", [1, 4]), + Column("feat1", [2, 5]), + Column("feat2", [3, 6]), + Column("target", [0, 1]), + ] + ).tag_columns(target_name="target", feature_names=["feat1", "feat2"]) @pytest.fixture() def invalid_data() -> TaggedTable: - table = Table.from_csv_file(resolve_resource_path("test_elastic_net_regression_invalid.csv")) - return table.tag_columns(target_name="T") + return Table.from_columns( + [ + Column("id", [1, 4]), + Column("feat1", ["a", 5]), + Column("feat2", [3, 6]), + Column("target", [0, 1]), + ] + ).tag_columns(target_name="target", feature_names=["feat1", "feat2"]) class TestFit: @@ -41,7 +53,7 @@ def test_should_include_features_of_prediction_input(self, regressor: Regressor, def test_should_set_correct_target_name(self, regressor: Regressor, valid_data: TaggedTable) -> None: fitted_regressor = regressor.fit(valid_data) prediction = fitted_regressor.predict(valid_data.features) - assert prediction.target.name == "T" + assert prediction.target.name == "target" def test_should_raise_when_not_fitted(self, regressor: Regressor, valid_data: TaggedTable) -> None: with pytest.raises(PredictionError): diff --git a/tests/safeds/ml/regression/test_gradient_boosting.py b/tests/safeds/ml/regression/test_gradient_boosting.py index f4970cd99..418182b35 100644 --- a/tests/safeds/ml/regression/test_gradient_boosting.py +++ b/tests/safeds/ml/regression/test_gradient_boosting.py @@ -1,8 +1,8 @@ import pytest -from safeds.data.tabular.containers import Table, TaggedTable + +from safeds.data.tabular.containers import Table, TaggedTable, Column from safeds.exceptions import LearningError, PredictionError from safeds.ml.regression import GradientBoosting, Regressor -from tests.helpers import resolve_resource_path @pytest.fixture() @@ -12,14 +12,26 @@ def regressor() -> Regressor: @pytest.fixture() def valid_data() -> TaggedTable: - table = Table.from_csv_file(resolve_resource_path("test_gradient_boosting_regression.csv")) - return table.tag_columns(target_name="T") + return Table.from_columns( + [ + Column("id", [1, 4]), + Column("feat1", [2, 5]), + Column("feat2", [3, 6]), + Column("target", [0, 1]), + ] + ).tag_columns(target_name="target", feature_names=["feat1", "feat2"]) @pytest.fixture() def invalid_data() -> TaggedTable: - table = Table.from_csv_file(resolve_resource_path("test_gradient_boosting_regression_invalid.csv")) - return table.tag_columns(target_name="T") + return Table.from_columns( + [ + Column("id", [1, 4]), + Column("feat1", ["a", 5]), + Column("feat2", [3, 6]), + Column("target", [0, 1]), + ] + ).tag_columns(target_name="target", feature_names=["feat1", "feat2"]) class TestFit: @@ -41,7 +53,7 @@ def test_should_include_features_of_prediction_input(self, regressor: Regressor, def test_should_set_correct_target_name(self, regressor: Regressor, valid_data: TaggedTable) -> None: fitted_regressor = regressor.fit(valid_data) prediction = fitted_regressor.predict(valid_data.features) - assert prediction.target.name == "T" + assert prediction.target.name == "target" def test_should_raise_when_not_fitted(self, regressor: Regressor, valid_data: TaggedTable) -> None: with pytest.raises(PredictionError): diff --git a/tests/safeds/ml/regression/test_k_nearest_neighbors.py b/tests/safeds/ml/regression/test_k_nearest_neighbors.py index 0b1b9eeec..da4035239 100644 --- a/tests/safeds/ml/regression/test_k_nearest_neighbors.py +++ b/tests/safeds/ml/regression/test_k_nearest_neighbors.py @@ -1,8 +1,8 @@ import pytest -from safeds.data.tabular.containers import Table, TaggedTable + +from safeds.data.tabular.containers import Table, TaggedTable, Column from safeds.exceptions import LearningError, PredictionError from safeds.ml.regression import KNearestNeighbors, Regressor -from tests.helpers import resolve_resource_path @pytest.fixture() @@ -12,14 +12,26 @@ def regressor() -> Regressor: @pytest.fixture() def valid_data() -> TaggedTable: - table = Table.from_csv_file(resolve_resource_path("test_k_nearest_neighbors.csv")) - return table.tag_columns(target_name="T") + return Table.from_columns( + [ + Column("id", [1, 4]), + Column("feat1", [2, 5]), + Column("feat2", [3, 6]), + Column("target", [0, 1]), + ] + ).tag_columns(target_name="target", feature_names=["feat1", "feat2"]) @pytest.fixture() def invalid_data() -> TaggedTable: - table = Table.from_csv_file(resolve_resource_path("test_k_nearest_neighbors_invalid.csv")) - return table.tag_columns(target_name="T") + return Table.from_columns( + [ + Column("id", [1, 4]), + Column("feat1", ["a", 5]), + Column("feat2", [3, 6]), + Column("target", [0, 1]), + ] + ).tag_columns(target_name="target", feature_names=["feat1", "feat2"]) class TestFit: @@ -41,7 +53,7 @@ def test_should_include_features_of_prediction_input(self, regressor: Regressor, def test_should_set_correct_target_name(self, regressor: Regressor, valid_data: TaggedTable) -> None: fitted_regressor = regressor.fit(valid_data) prediction = fitted_regressor.predict(valid_data.features) - assert prediction.target.name == "T" + assert prediction.target.name == "target" def test_should_raise_when_not_fitted(self, regressor: Regressor, valid_data: TaggedTable) -> None: with pytest.raises(PredictionError): diff --git a/tests/safeds/ml/regression/test_lasso_regression.py b/tests/safeds/ml/regression/test_lasso_regression.py index c008a68ac..492b670c2 100644 --- a/tests/safeds/ml/regression/test_lasso_regression.py +++ b/tests/safeds/ml/regression/test_lasso_regression.py @@ -1,8 +1,8 @@ import pytest -from safeds.data.tabular.containers import Table, TaggedTable + +from safeds.data.tabular.containers import Table, TaggedTable, Column from safeds.exceptions import LearningError, PredictionError from safeds.ml.regression import LassoRegression, Regressor -from tests.helpers import resolve_resource_path @pytest.fixture() @@ -12,14 +12,26 @@ def regressor() -> Regressor: @pytest.fixture() def valid_data() -> TaggedTable: - table = Table.from_csv_file(resolve_resource_path("test_lasso_regression.csv")) - return table.tag_columns(target_name="T") + return Table.from_columns( + [ + Column("id", [1, 4]), + Column("feat1", [2, 5]), + Column("feat2", [3, 6]), + Column("target", [0, 1]), + ] + ).tag_columns(target_name="target", feature_names=["feat1", "feat2"]) @pytest.fixture() def invalid_data() -> TaggedTable: - table = Table.from_csv_file(resolve_resource_path("test_lasso_regression_invalid.csv")) - return table.tag_columns(target_name="T") + return Table.from_columns( + [ + Column("id", [1, 4]), + Column("feat1", ["a", 5]), + Column("feat2", [3, 6]), + Column("target", [0, 1]), + ] + ).tag_columns(target_name="target", feature_names=["feat1", "feat2"]) class TestFit: @@ -41,7 +53,7 @@ def test_should_include_features_of_prediction_input(self, regressor: Regressor, def test_should_set_correct_target_name(self, regressor: Regressor, valid_data: TaggedTable) -> None: fitted_regressor = regressor.fit(valid_data) prediction = fitted_regressor.predict(valid_data.features) - assert prediction.target.name == "T" + assert prediction.target.name == "target" def test_should_raise_when_not_fitted(self, regressor: Regressor, valid_data: TaggedTable) -> None: with pytest.raises(PredictionError): diff --git a/tests/safeds/ml/regression/test_linear_regression.py b/tests/safeds/ml/regression/test_linear_regression.py index 58cc3fe58..fed27964e 100644 --- a/tests/safeds/ml/regression/test_linear_regression.py +++ b/tests/safeds/ml/regression/test_linear_regression.py @@ -1,8 +1,8 @@ import pytest -from safeds.data.tabular.containers import Table, TaggedTable + +from safeds.data.tabular.containers import Table, TaggedTable, Column from safeds.exceptions import LearningError, PredictionError from safeds.ml.regression import LinearRegression, Regressor -from tests.helpers import resolve_resource_path @pytest.fixture() @@ -12,14 +12,26 @@ def regressor() -> Regressor: @pytest.fixture() def valid_data() -> TaggedTable: - table = Table.from_csv_file(resolve_resource_path("test_linear_regression.csv")) - return table.tag_columns(target_name="T") + return Table.from_columns( + [ + Column("id", [1, 4]), + Column("feat1", [2, 5]), + Column("feat2", [3, 6]), + Column("target", [0, 1]), + ] + ).tag_columns(target_name="target", feature_names=["feat1", "feat2"]) @pytest.fixture() def invalid_data() -> TaggedTable: - table = Table.from_csv_file(resolve_resource_path("test_linear_regression_invalid.csv")) - return table.tag_columns(target_name="T") + return Table.from_columns( + [ + Column("id", [1, 4]), + Column("feat1", ["a", 5]), + Column("feat2", [3, 6]), + Column("target", [0, 1]), + ] + ).tag_columns(target_name="target", feature_names=["feat1", "feat2"]) class TestFit: @@ -41,7 +53,7 @@ def test_should_include_features_of_prediction_input(self, regressor: Regressor, def test_should_set_correct_target_name(self, regressor: Regressor, valid_data: TaggedTable) -> None: fitted_regressor = regressor.fit(valid_data) prediction = fitted_regressor.predict(valid_data.features) - assert prediction.target.name == "T" + assert prediction.target.name == "target" def test_should_raise_when_not_fitted(self, regressor: Regressor, valid_data: TaggedTable) -> None: with pytest.raises(PredictionError): diff --git a/tests/safeds/ml/regression/test_random_forest.py b/tests/safeds/ml/regression/test_random_forest.py index 235fee023..afcc11cac 100644 --- a/tests/safeds/ml/regression/test_random_forest.py +++ b/tests/safeds/ml/regression/test_random_forest.py @@ -1,8 +1,8 @@ import pytest -from safeds.data.tabular.containers import Table, TaggedTable + +from safeds.data.tabular.containers import Table, TaggedTable, Column from safeds.exceptions import LearningError, PredictionError from safeds.ml.regression import RandomForest, Regressor -from tests.helpers import resolve_resource_path @pytest.fixture() @@ -12,14 +12,26 @@ def regressor() -> Regressor: @pytest.fixture() def valid_data() -> TaggedTable: - table = Table.from_csv_file(resolve_resource_path("test_random_forest.csv")) - return table.tag_columns(target_name="T") + return Table.from_columns( + [ + Column("id", [1, 4]), + Column("feat1", [2, 5]), + Column("feat2", [3, 6]), + Column("target", [0, 1]), + ] + ).tag_columns(target_name="target", feature_names=["feat1", "feat2"]) @pytest.fixture() def invalid_data() -> TaggedTable: - table = Table.from_csv_file(resolve_resource_path("test_random_forest_invalid.csv")) - return table.tag_columns(target_name="T") + return Table.from_columns( + [ + Column("id", [1, 4]), + Column("feat1", ["a", 5]), + Column("feat2", [3, 6]), + Column("target", [0, 1]), + ] + ).tag_columns(target_name="target", feature_names=["feat1", "feat2"]) class TestFit: @@ -41,7 +53,7 @@ def test_should_include_features_of_prediction_input(self, regressor: Regressor, def test_should_set_correct_target_name(self, regressor: Regressor, valid_data: TaggedTable) -> None: fitted_regressor = regressor.fit(valid_data) prediction = fitted_regressor.predict(valid_data.features) - assert prediction.target.name == "T" + assert prediction.target.name == "target" def test_should_raise_when_not_fitted(self, regressor: Regressor, valid_data: TaggedTable) -> None: with pytest.raises(PredictionError): diff --git a/tests/safeds/ml/regression/test_regressor.py b/tests/safeds/ml/regression/test_regressor.py index ca802490c..075e92ecd 100644 --- a/tests/safeds/ml/regression/test_regressor.py +++ b/tests/safeds/ml/regression/test_regressor.py @@ -2,10 +2,10 @@ 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 diff --git a/tests/safeds/ml/regression/test_ridge_regression.py b/tests/safeds/ml/regression/test_ridge_regression.py index 321a9f147..942933c0c 100644 --- a/tests/safeds/ml/regression/test_ridge_regression.py +++ b/tests/safeds/ml/regression/test_ridge_regression.py @@ -1,8 +1,8 @@ import pytest -from safeds.data.tabular.containers import Table, TaggedTable + +from safeds.data.tabular.containers import Table, TaggedTable, Column from safeds.exceptions import LearningError, PredictionError from safeds.ml.regression import Regressor, RidgeRegression -from tests.helpers import resolve_resource_path @pytest.fixture() @@ -12,14 +12,26 @@ def regressor() -> Regressor: @pytest.fixture() def valid_data() -> TaggedTable: - table = Table.from_csv_file(resolve_resource_path("test_ridge_regression.csv")) - return table.tag_columns(target_name="T") + return Table.from_columns( + [ + Column("id", [1, 4]), + Column("feat1", [2, 5]), + Column("feat2", [3, 6]), + Column("target", [0, 1]), + ] + ).tag_columns(target_name="target", feature_names=["feat1", "feat2"]) @pytest.fixture() def invalid_data() -> TaggedTable: - table = Table.from_csv_file(resolve_resource_path("test_ridge_regression_invalid.csv")) - return table.tag_columns(target_name="T") + return Table.from_columns( + [ + Column("id", [1, 4]), + Column("feat1", ["a", 5]), + Column("feat2", [3, 6]), + Column("target", [0, 1]), + ] + ).tag_columns(target_name="target", feature_names=["feat1", "feat2"]) class TestFit: @@ -41,7 +53,7 @@ def test_should_include_features_of_prediction_input(self, regressor: Regressor, def test_should_set_correct_target_name(self, regressor: Regressor, valid_data: TaggedTable) -> None: fitted_regressor = regressor.fit(valid_data) prediction = fitted_regressor.predict(valid_data.features) - assert prediction.target.name == "T" + assert prediction.target.name == "target" def test_should_raise_when_not_fitted(self, regressor: Regressor, valid_data: TaggedTable) -> None: with pytest.raises(PredictionError): From a010ec83e502069dce40d03aaa8f2abb30aeac87 Mon Sep 17 00:00:00 2001 From: Lars Reimann Date: Wed, 29 Mar 2023 21:47:35 +0200 Subject: [PATCH 12/14] test: output of `predict` should include entire input --- tests/safeds/ml/classification/test_ada_boost.py | 5 +++++ .../safeds/ml/classification/test_decision_tree.py | 5 +++++ .../ml/classification/test_gradient_boosting.py | 5 +++++ .../ml/classification/test_k_nearest_neighbors.py | 6 +++++- .../ml/classification/test_logistic_regression.py | 5 +++++ .../safeds/ml/classification/test_random_forest.py | 5 +++++ tests/safeds/ml/regression/test_ada_boost.py | 13 +++++-------- tests/safeds/ml/regression/test_decision_tree.py | 5 +++++ tests/safeds/ml/regression/test_elastic_net.py | 5 +++++ .../safeds/ml/regression/test_gradient_boosting.py | 5 +++++ .../ml/regression/test_k_nearest_neighbors.py | 5 +++++ tests/safeds/ml/regression/test_lasso_regression.py | 5 +++++ .../safeds/ml/regression/test_linear_regression.py | 5 +++++ tests/safeds/ml/regression/test_random_forest.py | 5 +++++ tests/safeds/ml/regression/test_ridge_regression.py | 5 +++++ 15 files changed, 75 insertions(+), 9 deletions(-) diff --git a/tests/safeds/ml/classification/test_ada_boost.py b/tests/safeds/ml/classification/test_ada_boost.py index b7f2fe45e..9739b0246 100644 --- a/tests/safeds/ml/classification/test_ada_boost.py +++ b/tests/safeds/ml/classification/test_ada_boost.py @@ -50,6 +50,11 @@ def test_should_include_features_of_prediction_input(self, classifier: Classifie prediction = fitted_classifier.predict(valid_data.features) assert prediction.features == valid_data.features + def test_should_include_complete_prediction_input(self, classifier: Classifier, valid_data: TaggedTable) -> None: + fitted_regressor = classifier.fit(valid_data) + prediction = fitted_regressor.predict(valid_data.drop_columns(["target"])) + assert prediction.drop_columns(["target"]) == valid_data.drop_columns(["target"]) + def test_should_set_correct_target_name(self, classifier: Classifier, valid_data: TaggedTable) -> None: fitted_classifier = classifier.fit(valid_data) prediction = fitted_classifier.predict(valid_data.features) diff --git a/tests/safeds/ml/classification/test_decision_tree.py b/tests/safeds/ml/classification/test_decision_tree.py index 9b3e8065a..9bbbf2549 100644 --- a/tests/safeds/ml/classification/test_decision_tree.py +++ b/tests/safeds/ml/classification/test_decision_tree.py @@ -50,6 +50,11 @@ def test_should_include_features_of_prediction_input(self, classifier: Classifie prediction = fitted_classifier.predict(valid_data.features) assert prediction.features == valid_data.features + def test_should_include_complete_prediction_input(self, classifier: Classifier, valid_data: TaggedTable) -> None: + fitted_regressor = classifier.fit(valid_data) + prediction = fitted_regressor.predict(valid_data.drop_columns(["target"])) + assert prediction.drop_columns(["target"]) == valid_data.drop_columns(["target"]) + def test_should_set_correct_target_name(self, classifier: Classifier, valid_data: TaggedTable) -> None: fitted_classifier = classifier.fit(valid_data) prediction = fitted_classifier.predict(valid_data.features) diff --git a/tests/safeds/ml/classification/test_gradient_boosting.py b/tests/safeds/ml/classification/test_gradient_boosting.py index 417f4574d..192ea1988 100644 --- a/tests/safeds/ml/classification/test_gradient_boosting.py +++ b/tests/safeds/ml/classification/test_gradient_boosting.py @@ -50,6 +50,11 @@ def test_should_include_features_of_prediction_input(self, classifier: Classifie prediction = fitted_classifier.predict(valid_data.features) assert prediction.features == valid_data.features + def test_should_include_complete_prediction_input(self, classifier: Classifier, valid_data: TaggedTable) -> None: + fitted_regressor = classifier.fit(valid_data) + prediction = fitted_regressor.predict(valid_data.drop_columns(["target"])) + assert prediction.drop_columns(["target"]) == valid_data.drop_columns(["target"]) + def test_should_set_correct_target_name(self, classifier: Classifier, valid_data: TaggedTable) -> None: fitted_classifier = classifier.fit(valid_data) prediction = fitted_classifier.predict(valid_data.features) diff --git a/tests/safeds/ml/classification/test_k_nearest_neighbors.py b/tests/safeds/ml/classification/test_k_nearest_neighbors.py index ff1cf3b38..3e0c66865 100644 --- a/tests/safeds/ml/classification/test_k_nearest_neighbors.py +++ b/tests/safeds/ml/classification/test_k_nearest_neighbors.py @@ -3,7 +3,6 @@ from safeds.data.tabular.containers import Table, TaggedTable, Column from safeds.exceptions import LearningError, PredictionError from safeds.ml.classification import Classifier, KNearestNeighbors -from tests.helpers import resolve_resource_path @pytest.fixture() @@ -51,6 +50,11 @@ def test_should_include_features_of_prediction_input(self, classifier: Classifie prediction = fitted_classifier.predict(valid_data.features) assert prediction.features == valid_data.features + def test_should_include_complete_prediction_input(self, classifier: Classifier, valid_data: TaggedTable) -> None: + fitted_regressor = classifier.fit(valid_data) + prediction = fitted_regressor.predict(valid_data.drop_columns(["target"])) + assert prediction.drop_columns(["target"]) == valid_data.drop_columns(["target"]) + def test_should_set_correct_target_name(self, classifier: Classifier, valid_data: TaggedTable) -> None: fitted_classifier = classifier.fit(valid_data) prediction = fitted_classifier.predict(valid_data.features) diff --git a/tests/safeds/ml/classification/test_logistic_regression.py b/tests/safeds/ml/classification/test_logistic_regression.py index 0e0419451..26bfcfd6b 100644 --- a/tests/safeds/ml/classification/test_logistic_regression.py +++ b/tests/safeds/ml/classification/test_logistic_regression.py @@ -50,6 +50,11 @@ def test_should_include_features_of_prediction_input(self, classifier: Classifie prediction = fitted_classifier.predict(valid_data.features) assert prediction.features == valid_data.features + def test_should_include_complete_prediction_input(self, classifier: Classifier, valid_data: TaggedTable) -> None: + fitted_regressor = classifier.fit(valid_data) + prediction = fitted_regressor.predict(valid_data.drop_columns(["target"])) + assert prediction.drop_columns(["target"]) == valid_data.drop_columns(["target"]) + def test_should_set_correct_target_name(self, classifier: Classifier, valid_data: TaggedTable) -> None: fitted_classifier = classifier.fit(valid_data) prediction = fitted_classifier.predict(valid_data.features) diff --git a/tests/safeds/ml/classification/test_random_forest.py b/tests/safeds/ml/classification/test_random_forest.py index d56f4d119..2363c6c33 100644 --- a/tests/safeds/ml/classification/test_random_forest.py +++ b/tests/safeds/ml/classification/test_random_forest.py @@ -50,6 +50,11 @@ def test_should_include_features_of_prediction_input(self, classifier: Classifie prediction = fitted_classifier.predict(valid_data.features) assert prediction.features == valid_data.features + def test_should_include_complete_prediction_input(self, classifier: Classifier, valid_data: TaggedTable) -> None: + fitted_regressor = classifier.fit(valid_data) + prediction = fitted_regressor.predict(valid_data.drop_columns(["target"])) + assert prediction.drop_columns(["target"]) == valid_data.drop_columns(["target"]) + def test_should_set_correct_target_name(self, classifier: Classifier, valid_data: TaggedTable) -> None: fitted_classifier = classifier.fit(valid_data) prediction = fitted_classifier.predict(valid_data.features) diff --git a/tests/safeds/ml/regression/test_ada_boost.py b/tests/safeds/ml/regression/test_ada_boost.py index 3acbc0027..53ef05883 100644 --- a/tests/safeds/ml/regression/test_ada_boost.py +++ b/tests/safeds/ml/regression/test_ada_boost.py @@ -50,19 +50,16 @@ def test_should_include_features_of_prediction_input(self, regressor: Regressor, prediction = fitted_regressor.predict(valid_data.features) assert prediction.features == valid_data.features + def test_should_include_complete_prediction_input(self, regressor: Regressor, valid_data: TaggedTable) -> None: + fitted_regressor = regressor.fit(valid_data) + prediction = fitted_regressor.predict(valid_data.drop_columns(["target"])) + assert prediction.drop_columns(["target"]) == valid_data.drop_columns(["target"]) + def test_should_set_correct_target_name(self, regressor: Regressor, valid_data: TaggedTable) -> None: fitted_regressor = regressor.fit(valid_data) prediction = fitted_regressor.predict(valid_data.features) assert prediction.target.name == "target" - def test_should_include_other_columns_of_prediction_input(self, regressor: Regressor, valid_data: TaggedTable) -> None: - fitted_regressor = regressor.fit(valid_data) - prediction = fitted_regressor.predict(valid_data.drop_columns(["target"])) - other_column_names = list( - set(valid_data.get_column_names()) - set(valid_data.features.get_column_names()) - {valid_data.target.name} - ) - assert prediction.keep_only_columns(other_column_names) == valid_data.keep_only_columns(other_column_names) - def test_should_raise_when_not_fitted(self, regressor: Regressor, valid_data: TaggedTable) -> None: with pytest.raises(PredictionError): regressor.predict(valid_data.features) diff --git a/tests/safeds/ml/regression/test_decision_tree.py b/tests/safeds/ml/regression/test_decision_tree.py index f9856bfd9..6adc1472f 100644 --- a/tests/safeds/ml/regression/test_decision_tree.py +++ b/tests/safeds/ml/regression/test_decision_tree.py @@ -50,6 +50,11 @@ def test_should_include_features_of_prediction_input(self, regressor: Regressor, prediction = fitted_regressor.predict(valid_data.features) assert prediction.features == valid_data.features + def test_should_include_complete_prediction_input(self, regressor: Regressor, valid_data: TaggedTable) -> None: + fitted_regressor = regressor.fit(valid_data) + prediction = fitted_regressor.predict(valid_data.drop_columns(["target"])) + assert prediction.drop_columns(["target"]) == valid_data.drop_columns(["target"]) + def test_should_set_correct_target_name(self, regressor: Regressor, valid_data: TaggedTable) -> None: fitted_regressor = regressor.fit(valid_data) prediction = fitted_regressor.predict(valid_data.features) diff --git a/tests/safeds/ml/regression/test_elastic_net.py b/tests/safeds/ml/regression/test_elastic_net.py index ded342ffe..c953568fb 100644 --- a/tests/safeds/ml/regression/test_elastic_net.py +++ b/tests/safeds/ml/regression/test_elastic_net.py @@ -50,6 +50,11 @@ def test_should_include_features_of_prediction_input(self, regressor: Regressor, prediction = fitted_regressor.predict(valid_data.features) assert prediction.features == valid_data.features + def test_should_include_complete_prediction_input(self, regressor: Regressor, valid_data: TaggedTable) -> None: + fitted_regressor = regressor.fit(valid_data) + prediction = fitted_regressor.predict(valid_data.drop_columns(["target"])) + assert prediction.drop_columns(["target"]) == valid_data.drop_columns(["target"]) + def test_should_set_correct_target_name(self, regressor: Regressor, valid_data: TaggedTable) -> None: fitted_regressor = regressor.fit(valid_data) prediction = fitted_regressor.predict(valid_data.features) diff --git a/tests/safeds/ml/regression/test_gradient_boosting.py b/tests/safeds/ml/regression/test_gradient_boosting.py index 418182b35..aeb140ea7 100644 --- a/tests/safeds/ml/regression/test_gradient_boosting.py +++ b/tests/safeds/ml/regression/test_gradient_boosting.py @@ -50,6 +50,11 @@ def test_should_include_features_of_prediction_input(self, regressor: Regressor, prediction = fitted_regressor.predict(valid_data.features) assert prediction.features == valid_data.features + def test_should_include_complete_prediction_input(self, regressor: Regressor, valid_data: TaggedTable) -> None: + fitted_regressor = regressor.fit(valid_data) + prediction = fitted_regressor.predict(valid_data.drop_columns(["target"])) + assert prediction.drop_columns(["target"]) == valid_data.drop_columns(["target"]) + def test_should_set_correct_target_name(self, regressor: Regressor, valid_data: TaggedTable) -> None: fitted_regressor = regressor.fit(valid_data) prediction = fitted_regressor.predict(valid_data.features) diff --git a/tests/safeds/ml/regression/test_k_nearest_neighbors.py b/tests/safeds/ml/regression/test_k_nearest_neighbors.py index da4035239..f7c1cc947 100644 --- a/tests/safeds/ml/regression/test_k_nearest_neighbors.py +++ b/tests/safeds/ml/regression/test_k_nearest_neighbors.py @@ -50,6 +50,11 @@ def test_should_include_features_of_prediction_input(self, regressor: Regressor, prediction = fitted_regressor.predict(valid_data.features) assert prediction.features == valid_data.features + def test_should_include_complete_prediction_input(self, regressor: Regressor, valid_data: TaggedTable) -> None: + fitted_regressor = regressor.fit(valid_data) + prediction = fitted_regressor.predict(valid_data.drop_columns(["target"])) + assert prediction.drop_columns(["target"]) == valid_data.drop_columns(["target"]) + def test_should_set_correct_target_name(self, regressor: Regressor, valid_data: TaggedTable) -> None: fitted_regressor = regressor.fit(valid_data) prediction = fitted_regressor.predict(valid_data.features) diff --git a/tests/safeds/ml/regression/test_lasso_regression.py b/tests/safeds/ml/regression/test_lasso_regression.py index 492b670c2..a31322362 100644 --- a/tests/safeds/ml/regression/test_lasso_regression.py +++ b/tests/safeds/ml/regression/test_lasso_regression.py @@ -50,6 +50,11 @@ def test_should_include_features_of_prediction_input(self, regressor: Regressor, prediction = fitted_regressor.predict(valid_data.features) assert prediction.features == valid_data.features + def test_should_include_complete_prediction_input(self, regressor: Regressor, valid_data: TaggedTable) -> None: + fitted_regressor = regressor.fit(valid_data) + prediction = fitted_regressor.predict(valid_data.drop_columns(["target"])) + assert prediction.drop_columns(["target"]) == valid_data.drop_columns(["target"]) + def test_should_set_correct_target_name(self, regressor: Regressor, valid_data: TaggedTable) -> None: fitted_regressor = regressor.fit(valid_data) prediction = fitted_regressor.predict(valid_data.features) diff --git a/tests/safeds/ml/regression/test_linear_regression.py b/tests/safeds/ml/regression/test_linear_regression.py index fed27964e..95d489a7e 100644 --- a/tests/safeds/ml/regression/test_linear_regression.py +++ b/tests/safeds/ml/regression/test_linear_regression.py @@ -50,6 +50,11 @@ def test_should_include_features_of_prediction_input(self, regressor: Regressor, prediction = fitted_regressor.predict(valid_data.features) assert prediction.features == valid_data.features + def test_should_include_complete_prediction_input(self, regressor: Regressor, valid_data: TaggedTable) -> None: + fitted_regressor = regressor.fit(valid_data) + prediction = fitted_regressor.predict(valid_data.drop_columns(["target"])) + assert prediction.drop_columns(["target"]) == valid_data.drop_columns(["target"]) + def test_should_set_correct_target_name(self, regressor: Regressor, valid_data: TaggedTable) -> None: fitted_regressor = regressor.fit(valid_data) prediction = fitted_regressor.predict(valid_data.features) diff --git a/tests/safeds/ml/regression/test_random_forest.py b/tests/safeds/ml/regression/test_random_forest.py index afcc11cac..5f112ee51 100644 --- a/tests/safeds/ml/regression/test_random_forest.py +++ b/tests/safeds/ml/regression/test_random_forest.py @@ -50,6 +50,11 @@ def test_should_include_features_of_prediction_input(self, regressor: Regressor, prediction = fitted_regressor.predict(valid_data.features) assert prediction.features == valid_data.features + def test_should_include_complete_prediction_input(self, regressor: Regressor, valid_data: TaggedTable) -> None: + fitted_regressor = regressor.fit(valid_data) + prediction = fitted_regressor.predict(valid_data.drop_columns(["target"])) + assert prediction.drop_columns(["target"]) == valid_data.drop_columns(["target"]) + def test_should_set_correct_target_name(self, regressor: Regressor, valid_data: TaggedTable) -> None: fitted_regressor = regressor.fit(valid_data) prediction = fitted_regressor.predict(valid_data.features) diff --git a/tests/safeds/ml/regression/test_ridge_regression.py b/tests/safeds/ml/regression/test_ridge_regression.py index 942933c0c..33a3a445c 100644 --- a/tests/safeds/ml/regression/test_ridge_regression.py +++ b/tests/safeds/ml/regression/test_ridge_regression.py @@ -50,6 +50,11 @@ def test_should_include_features_of_prediction_input(self, regressor: Regressor, prediction = fitted_regressor.predict(valid_data.features) assert prediction.features == valid_data.features + def test_should_include_complete_prediction_input(self, regressor: Regressor, valid_data: TaggedTable) -> None: + fitted_regressor = regressor.fit(valid_data) + prediction = fitted_regressor.predict(valid_data.drop_columns(["target"])) + assert prediction.drop_columns(["target"]) == valid_data.drop_columns(["target"]) + def test_should_set_correct_target_name(self, regressor: Regressor, valid_data: TaggedTable) -> None: fitted_regressor = regressor.fit(valid_data) prediction = fitted_regressor.predict(valid_data.features) From 8d86a91e6cdd359be41261b5e0ba107d95135c25 Mon Sep 17 00:00:00 2001 From: lars-reimann Date: Wed, 29 Mar 2023 19:58:39 +0000 Subject: [PATCH 13/14] style: apply automated linter fixes --- .../containers/_table/test_column_drop.py | 4 +--- .../containers/_table/test_from_csv_file.py | 9 ++------- .../containers/_table/test_from_json_file.py | 13 +++---------- .../containers/_table/test_keep_only_columns.py | 4 +--- .../tabular/containers/_table/test_rename.py | 12 +++--------- .../containers/_table/test_replace_column.py | 8 ++------ .../containers/_table/test_table_add_column.py | 16 ++++------------ .../containers/_table/test_transform_column.py | 16 ++++------------ tests/safeds/ml/classification/test_ada_boost.py | 3 +-- .../safeds/ml/classification/test_classifier.py | 1 - .../ml/classification/test_decision_tree.py | 3 +-- .../ml/classification/test_gradient_boosting.py | 3 +-- .../classification/test_k_nearest_neighbors.py | 3 +-- .../classification/test_logistic_regression.py | 3 +-- .../ml/classification/test_random_forest.py | 3 +-- tests/safeds/ml/regression/test_ada_boost.py | 3 +-- tests/safeds/ml/regression/test_decision_tree.py | 3 +-- tests/safeds/ml/regression/test_elastic_net.py | 3 +-- .../ml/regression/test_gradient_boosting.py | 3 +-- .../ml/regression/test_k_nearest_neighbors.py | 3 +-- .../ml/regression/test_lasso_regression.py | 3 +-- .../ml/regression/test_linear_regression.py | 3 +-- tests/safeds/ml/regression/test_random_forest.py | 3 +-- tests/safeds/ml/regression/test_regressor.py | 2 +- .../ml/regression/test_ridge_regression.py | 3 +-- 25 files changed, 36 insertions(+), 94 deletions(-) diff --git a/tests/safeds/data/tabular/containers/_table/test_column_drop.py b/tests/safeds/data/tabular/containers/_table/test_column_drop.py index e4ad6efe8..a583ac3b1 100644 --- a/tests/safeds/data/tabular/containers/_table/test_column_drop.py +++ b/tests/safeds/data/tabular/containers/_table/test_column_drop.py @@ -7,9 +7,7 @@ def test_table_column_drop() -> None: table = Table.from_csv_file(resolve_resource_path("test_table_from_csv_file.csv")) transformed_table = table.drop_columns(["A"]) - assert transformed_table.schema.has_column( - "B" - ) and not transformed_table.schema.has_column("A") + assert transformed_table.schema.has_column("B") and not transformed_table.schema.has_column("A") def test_table_column_drop_warning() -> None: diff --git a/tests/safeds/data/tabular/containers/_table/test_from_csv_file.py b/tests/safeds/data/tabular/containers/_table/test_from_csv_file.py index c0dc4899d..e0c1d0e54 100644 --- a/tests/safeds/data/tabular/containers/_table/test_from_csv_file.py +++ b/tests/safeds/data/tabular/containers/_table/test_from_csv_file.py @@ -5,14 +5,9 @@ def test_from_csv_file_valid() -> None: table = Table.from_csv_file(resolve_resource_path("test_table_from_csv_file.csv")) - assert ( - table.get_column("A").get_value(0) == 1 - and table.get_column("B").get_value(0) == 2 - ) + assert table.get_column("A").get_value(0) == 1 and table.get_column("B").get_value(0) == 2 def test_from_csv_file_invalid() -> None: with pytest.raises(FileNotFoundError): - Table.from_csv_file( - resolve_resource_path("test_table_from_csv_file_invalid.csv") - ) + Table.from_csv_file(resolve_resource_path("test_table_from_csv_file_invalid.csv")) diff --git a/tests/safeds/data/tabular/containers/_table/test_from_json_file.py b/tests/safeds/data/tabular/containers/_table/test_from_json_file.py index a970232da..112fd78dd 100644 --- a/tests/safeds/data/tabular/containers/_table/test_from_json_file.py +++ b/tests/safeds/data/tabular/containers/_table/test_from_json_file.py @@ -4,17 +4,10 @@ def test_from_json_file_valid() -> None: - table = Table.from_json_file( - resolve_resource_path("test_table_from_json_file.json") - ) - assert ( - table.get_column("A").get_value(0) == 1 - and table.get_column("B").get_value(0) == 2 - ) + table = Table.from_json_file(resolve_resource_path("test_table_from_json_file.json")) + assert table.get_column("A").get_value(0) == 1 and table.get_column("B").get_value(0) == 2 def test_from_json_file_invalid() -> None: with pytest.raises(FileNotFoundError): - Table.from_json_file( - resolve_resource_path("test_table_from_json_file_invalid.json") - ) + Table.from_json_file(resolve_resource_path("test_table_from_json_file_invalid.json")) diff --git a/tests/safeds/data/tabular/containers/_table/test_keep_only_columns.py b/tests/safeds/data/tabular/containers/_table/test_keep_only_columns.py index 939107740..76b568934 100644 --- a/tests/safeds/data/tabular/containers/_table/test_keep_only_columns.py +++ b/tests/safeds/data/tabular/containers/_table/test_keep_only_columns.py @@ -7,9 +7,7 @@ def test_keep_columns() -> None: table = Table.from_csv_file(resolve_resource_path("test_table_from_csv_file.csv")) transformed_table = table.keep_only_columns(["A"]) - assert transformed_table.schema.has_column( - "A" - ) and not transformed_table.schema.has_column("B") + assert transformed_table.schema.has_column("A") and not transformed_table.schema.has_column("B") def test_keep_columns_warning() -> None: diff --git a/tests/safeds/data/tabular/containers/_table/test_rename.py b/tests/safeds/data/tabular/containers/_table/test_rename.py index 69a4a082c..c4799aca1 100644 --- a/tests/safeds/data/tabular/containers/_table/test_rename.py +++ b/tests/safeds/data/tabular/containers/_table/test_rename.py @@ -8,12 +8,8 @@ "name_from, name_to, column_one, column_two", [("A", "D", "D", "B"), ("A", "A", "A", "B")], ) -def test_rename_valid( - name_from: str, name_to: str, column_one: str, column_two: str -) -> None: - table: Table = Table.from_csv_file( - resolve_resource_path("test_table_from_csv_file.csv") - ) +def test_rename_valid(name_from: str, name_to: str, column_one: str, column_two: str) -> None: + table: Table = Table.from_csv_file(resolve_resource_path("test_table_from_csv_file.csv")) renamed_table = table.rename_column(name_from, name_to) assert renamed_table.schema.has_column(column_one) assert renamed_table.schema.has_column(column_two) @@ -29,8 +25,6 @@ def test_rename_valid( ], ) def test_rename_invalid(name_from: str, name_to: str, error: Exception) -> None: - table: Table = Table.from_csv_file( - resolve_resource_path("test_table_from_csv_file.csv") - ) + table: Table = Table.from_csv_file(resolve_resource_path("test_table_from_csv_file.csv")) with pytest.raises(error): table.rename_column(name_from, name_to) diff --git a/tests/safeds/data/tabular/containers/_table/test_replace_column.py b/tests/safeds/data/tabular/containers/_table/test_replace_column.py index 1c211ca3e..f383d38b3 100644 --- a/tests/safeds/data/tabular/containers/_table/test_replace_column.py +++ b/tests/safeds/data/tabular/containers/_table/test_replace_column.py @@ -17,9 +17,7 @@ ], ) def test_replace_valid(column_name: str, path: str) -> None: - input_table: Table = Table.from_csv_file( - resolve_resource_path("test_table_replace_column_input.csv") - ) + input_table: Table = Table.from_csv_file(resolve_resource_path("test_table_replace_column_input.csv")) expected: Table = Table.from_csv_file(resolve_resource_path(path)) column = Column(column_name, pd.Series(["d", "e", "f"])) @@ -43,9 +41,7 @@ def test_replace_invalid( column_name: str, error: type[Exception], ) -> None: - input_table: Table = Table.from_csv_file( - resolve_resource_path("test_table_replace_column_input.csv") - ) + input_table: Table = Table.from_csv_file(resolve_resource_path("test_table_replace_column_input.csv")) column = Column(column_name, pd.Series(column_values)) with pytest.raises(error): diff --git a/tests/safeds/data/tabular/containers/_table/test_table_add_column.py b/tests/safeds/data/tabular/containers/_table/test_table_add_column.py index da88bf37d..b46bb2b67 100644 --- a/tests/safeds/data/tabular/containers/_table/test_table_add_column.py +++ b/tests/safeds/data/tabular/containers/_table/test_table_add_column.py @@ -6,12 +6,8 @@ def test_table_add_column_valid() -> None: - input_table = Table.from_csv_file( - resolve_resource_path("test_table_add_column_valid_input.csv") - ) - expected = Table.from_csv_file( - resolve_resource_path("test_table_add_column_valid_output.csv") - ) + input_table = Table.from_csv_file(resolve_resource_path("test_table_add_column_valid_input.csv")) + expected = Table.from_csv_file(resolve_resource_path("test_table_add_column_valid_output.csv")) column = Column("C", pd.Series(["a", "b", "c"])) result = input_table.add_column(column) @@ -25,12 +21,8 @@ def test_table_add_column_valid() -> None: (["a", "b"], "C", ColumnSizeError), ], ) -def test_table_add_column_( - column_values: list[str], column_name: str, error: type[Exception] -) -> None: - input_table = Table.from_csv_file( - resolve_resource_path("test_table_add_column_valid_input.csv") - ) +def test_table_add_column_(column_values: list[str], column_name: str, error: type[Exception]) -> None: + input_table = Table.from_csv_file(resolve_resource_path("test_table_add_column_valid_input.csv")) column = Column(column_name, pd.Series(column_values)) with pytest.raises(error): diff --git a/tests/safeds/data/tabular/containers/_table/test_transform_column.py b/tests/safeds/data/tabular/containers/_table/test_transform_column.py index 16dc5a3e6..9eeecc361 100644 --- a/tests/safeds/data/tabular/containers/_table/test_transform_column.py +++ b/tests/safeds/data/tabular/containers/_table/test_transform_column.py @@ -5,23 +5,15 @@ def test_transform_column_valid() -> None: - input_table: Table = Table.from_csv_file( - resolve_resource_path("test_table_transform_column.csv") - ) + input_table: Table = Table.from_csv_file(resolve_resource_path("test_table_transform_column.csv")) - result: Table = input_table.transform_column( - "A", lambda row: row.get_value("A") * 2 - ) + result: Table = input_table.transform_column("A", lambda row: row.get_value("A") * 2) - assert result == Table.from_csv_file( - resolve_resource_path("test_table_transform_column_output.csv") - ) + assert result == Table.from_csv_file(resolve_resource_path("test_table_transform_column_output.csv")) def test_transform_column_invalid() -> None: - input_table: Table = Table.from_csv_file( - resolve_resource_path("test_table_transform_column.csv") - ) + input_table: Table = Table.from_csv_file(resolve_resource_path("test_table_transform_column.csv")) with pytest.raises(UnknownColumnNameError): input_table.transform_column("D", lambda row: row.get_value("A") * 2) diff --git a/tests/safeds/ml/classification/test_ada_boost.py b/tests/safeds/ml/classification/test_ada_boost.py index 9739b0246..9e1e36f80 100644 --- a/tests/safeds/ml/classification/test_ada_boost.py +++ b/tests/safeds/ml/classification/test_ada_boost.py @@ -1,6 +1,5 @@ import pytest - -from safeds.data.tabular.containers import Table, TaggedTable, Column +from safeds.data.tabular.containers import Column, Table, TaggedTable from safeds.exceptions import LearningError, PredictionError from safeds.ml.classification import AdaBoost, Classifier diff --git a/tests/safeds/ml/classification/test_classifier.py b/tests/safeds/ml/classification/test_classifier.py index 4bc6a76e6..be48ab662 100644 --- a/tests/safeds/ml/classification/test_classifier.py +++ b/tests/safeds/ml/classification/test_classifier.py @@ -1,7 +1,6 @@ from __future__ import annotations import pandas as pd - from safeds.data.tabular.containers import Column, Table, TaggedTable from safeds.ml.classification import Classifier diff --git a/tests/safeds/ml/classification/test_decision_tree.py b/tests/safeds/ml/classification/test_decision_tree.py index 9bbbf2549..ce605ad04 100644 --- a/tests/safeds/ml/classification/test_decision_tree.py +++ b/tests/safeds/ml/classification/test_decision_tree.py @@ -1,6 +1,5 @@ import pytest - -from safeds.data.tabular.containers import Table, TaggedTable, Column +from safeds.data.tabular.containers import Column, Table, TaggedTable from safeds.exceptions import LearningError, PredictionError from safeds.ml.classification import Classifier, DecisionTree diff --git a/tests/safeds/ml/classification/test_gradient_boosting.py b/tests/safeds/ml/classification/test_gradient_boosting.py index 192ea1988..f050e204b 100644 --- a/tests/safeds/ml/classification/test_gradient_boosting.py +++ b/tests/safeds/ml/classification/test_gradient_boosting.py @@ -1,6 +1,5 @@ import pytest - -from safeds.data.tabular.containers import Table, TaggedTable, Column +from safeds.data.tabular.containers import Column, Table, TaggedTable from safeds.exceptions import LearningError, PredictionError from safeds.ml.classification import Classifier, GradientBoosting diff --git a/tests/safeds/ml/classification/test_k_nearest_neighbors.py b/tests/safeds/ml/classification/test_k_nearest_neighbors.py index 3e0c66865..066be1514 100644 --- a/tests/safeds/ml/classification/test_k_nearest_neighbors.py +++ b/tests/safeds/ml/classification/test_k_nearest_neighbors.py @@ -1,6 +1,5 @@ import pytest - -from safeds.data.tabular.containers import Table, TaggedTable, Column +from safeds.data.tabular.containers import Column, Table, TaggedTable from safeds.exceptions import LearningError, PredictionError from safeds.ml.classification import Classifier, KNearestNeighbors diff --git a/tests/safeds/ml/classification/test_logistic_regression.py b/tests/safeds/ml/classification/test_logistic_regression.py index 26bfcfd6b..99cfb6f7e 100644 --- a/tests/safeds/ml/classification/test_logistic_regression.py +++ b/tests/safeds/ml/classification/test_logistic_regression.py @@ -1,6 +1,5 @@ import pytest - -from safeds.data.tabular.containers import Table, TaggedTable, Column +from safeds.data.tabular.containers import Column, Table, TaggedTable from safeds.exceptions import LearningError, PredictionError from safeds.ml.classification import Classifier, LogisticRegression diff --git a/tests/safeds/ml/classification/test_random_forest.py b/tests/safeds/ml/classification/test_random_forest.py index 2363c6c33..7a147e3dd 100644 --- a/tests/safeds/ml/classification/test_random_forest.py +++ b/tests/safeds/ml/classification/test_random_forest.py @@ -1,6 +1,5 @@ import pytest - -from safeds.data.tabular.containers import Table, TaggedTable, Column +from safeds.data.tabular.containers import Column, Table, TaggedTable from safeds.exceptions import LearningError, PredictionError from safeds.ml.classification import Classifier, RandomForest diff --git a/tests/safeds/ml/regression/test_ada_boost.py b/tests/safeds/ml/regression/test_ada_boost.py index 53ef05883..43985fbad 100644 --- a/tests/safeds/ml/regression/test_ada_boost.py +++ b/tests/safeds/ml/regression/test_ada_boost.py @@ -1,6 +1,5 @@ import pytest - -from safeds.data.tabular.containers import Table, TaggedTable, Column +from safeds.data.tabular.containers import Column, Table, TaggedTable from safeds.exceptions import LearningError, PredictionError from safeds.ml.regression import AdaBoost, Regressor diff --git a/tests/safeds/ml/regression/test_decision_tree.py b/tests/safeds/ml/regression/test_decision_tree.py index 6adc1472f..1e8e93589 100644 --- a/tests/safeds/ml/regression/test_decision_tree.py +++ b/tests/safeds/ml/regression/test_decision_tree.py @@ -1,6 +1,5 @@ import pytest - -from safeds.data.tabular.containers import Table, TaggedTable, Column +from safeds.data.tabular.containers import Column, Table, TaggedTable from safeds.exceptions import LearningError, PredictionError from safeds.ml.regression import DecisionTree, Regressor diff --git a/tests/safeds/ml/regression/test_elastic_net.py b/tests/safeds/ml/regression/test_elastic_net.py index c953568fb..aed84ae6d 100644 --- a/tests/safeds/ml/regression/test_elastic_net.py +++ b/tests/safeds/ml/regression/test_elastic_net.py @@ -1,6 +1,5 @@ import pytest - -from safeds.data.tabular.containers import Table, TaggedTable, Column +from safeds.data.tabular.containers import Column, Table, TaggedTable from safeds.exceptions import LearningError, PredictionError from safeds.ml.regression import ElasticNetRegression, Regressor diff --git a/tests/safeds/ml/regression/test_gradient_boosting.py b/tests/safeds/ml/regression/test_gradient_boosting.py index aeb140ea7..5d88166e6 100644 --- a/tests/safeds/ml/regression/test_gradient_boosting.py +++ b/tests/safeds/ml/regression/test_gradient_boosting.py @@ -1,6 +1,5 @@ import pytest - -from safeds.data.tabular.containers import Table, TaggedTable, Column +from safeds.data.tabular.containers import Column, Table, TaggedTable from safeds.exceptions import LearningError, PredictionError from safeds.ml.regression import GradientBoosting, Regressor diff --git a/tests/safeds/ml/regression/test_k_nearest_neighbors.py b/tests/safeds/ml/regression/test_k_nearest_neighbors.py index f7c1cc947..191eb69f3 100644 --- a/tests/safeds/ml/regression/test_k_nearest_neighbors.py +++ b/tests/safeds/ml/regression/test_k_nearest_neighbors.py @@ -1,6 +1,5 @@ import pytest - -from safeds.data.tabular.containers import Table, TaggedTable, Column +from safeds.data.tabular.containers import Column, Table, TaggedTable from safeds.exceptions import LearningError, PredictionError from safeds.ml.regression import KNearestNeighbors, Regressor diff --git a/tests/safeds/ml/regression/test_lasso_regression.py b/tests/safeds/ml/regression/test_lasso_regression.py index a31322362..94f91c32d 100644 --- a/tests/safeds/ml/regression/test_lasso_regression.py +++ b/tests/safeds/ml/regression/test_lasso_regression.py @@ -1,6 +1,5 @@ import pytest - -from safeds.data.tabular.containers import Table, TaggedTable, Column +from safeds.data.tabular.containers import Column, Table, TaggedTable from safeds.exceptions import LearningError, PredictionError from safeds.ml.regression import LassoRegression, Regressor diff --git a/tests/safeds/ml/regression/test_linear_regression.py b/tests/safeds/ml/regression/test_linear_regression.py index 95d489a7e..190fde4c4 100644 --- a/tests/safeds/ml/regression/test_linear_regression.py +++ b/tests/safeds/ml/regression/test_linear_regression.py @@ -1,6 +1,5 @@ import pytest - -from safeds.data.tabular.containers import Table, TaggedTable, Column +from safeds.data.tabular.containers import Column, Table, TaggedTable from safeds.exceptions import LearningError, PredictionError from safeds.ml.regression import LinearRegression, Regressor diff --git a/tests/safeds/ml/regression/test_random_forest.py b/tests/safeds/ml/regression/test_random_forest.py index 5f112ee51..5208eb325 100644 --- a/tests/safeds/ml/regression/test_random_forest.py +++ b/tests/safeds/ml/regression/test_random_forest.py @@ -1,6 +1,5 @@ import pytest - -from safeds.data.tabular.containers import Table, TaggedTable, Column +from safeds.data.tabular.containers import Column, Table, TaggedTable from safeds.exceptions import LearningError, PredictionError from safeds.ml.regression import RandomForest, Regressor diff --git a/tests/safeds/ml/regression/test_regressor.py b/tests/safeds/ml/regression/test_regressor.py index 075e92ecd..ca802490c 100644 --- a/tests/safeds/ml/regression/test_regressor.py +++ b/tests/safeds/ml/regression/test_regressor.py @@ -2,10 +2,10 @@ 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 diff --git a/tests/safeds/ml/regression/test_ridge_regression.py b/tests/safeds/ml/regression/test_ridge_regression.py index 33a3a445c..2c2a0beca 100644 --- a/tests/safeds/ml/regression/test_ridge_regression.py +++ b/tests/safeds/ml/regression/test_ridge_regression.py @@ -1,6 +1,5 @@ import pytest - -from safeds.data.tabular.containers import Table, TaggedTable, Column +from safeds.data.tabular.containers import Column, Table, TaggedTable from safeds.exceptions import LearningError, PredictionError from safeds.ml.regression import Regressor, RidgeRegression From a66289fd5cdbea477fa4bc45c127db38933bd221 Mon Sep 17 00:00:00 2001 From: Lars Reimann Date: Wed, 29 Mar 2023 21:58:49 +0200 Subject: [PATCH 14/14] docs: add missing word --- docs/tutorials/machine_learning.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/machine_learning.ipynb b/docs/tutorials/machine_learning.ipynb index 2a172ec27..bd8867b93 100644 --- a/docs/tutorials/machine_learning.ipynb +++ b/docs/tutorials/machine_learning.ipynb @@ -10,7 +10,7 @@ "## Create a `TaggedTable`\n", "\n", "First, we need to create a `TaggedTable` from the training data. `TaggedTable`s are used to train supervised machine learning models, because they keep track of the target\n", - "column. A `TaggedTable` can be created from a `Table` calling the `tag_columns` method:" + "column. A `TaggedTable` can be created from a `Table` by calling the `tag_columns` method:" ], "metadata": { "collapsed": false