Skip to content

Commit

Permalink
feat: Getters for hyperparameters of Regression and Classification mo…
Browse files Browse the repository at this point in the history
…dels (#306)

Closes #260 .

### Summary of Changes

Added properties/getters for the hyperparameters of all Regression and
Classification models.

---------

Co-authored-by: megalinter-bot <[email protected]>
  • Loading branch information
PhilipGutberlet and megalinter-bot authored May 25, 2023
1 parent 7803296 commit 5c7a662
Show file tree
Hide file tree
Showing 26 changed files with 106 additions and 24 deletions.
20 changes: 16 additions & 4 deletions src/safeds/ml/classical/classification/_ada_boost.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,18 @@ def __init__(
self._feature_names: list[str] | None = None
self._target_name: str | None = None

@property
def learner(self) -> Classifier | None:
return self._learner

@property
def maximum_number_of_learners(self) -> int:
return self._maximum_number_of_learners

@property
def learning_rate(self) -> float:
return self._learning_rate

def fit(self, training_set: TaggedTable) -> AdaBoost:
"""
Create a copy of this classifier and fit it with the given training data.
Expand All @@ -83,8 +95,8 @@ def fit(self, training_set: TaggedTable) -> AdaBoost:
fit(wrapped_classifier, training_set)

result = AdaBoost(
learner=self._learner,
maximum_number_of_learners=self._maximum_number_of_learners,
learner=self.learner,
maximum_number_of_learners=self.maximum_number_of_learners,
learning_rate=self._learning_rate,
)
result._wrapped_classifier = wrapped_classifier
Expand Down Expand Up @@ -140,9 +152,9 @@ def _get_sklearn_classifier(self) -> ClassifierMixin:
wrapped_classifier: ClassifierMixin
The sklearn Classifier.
"""
learner = self._learner._get_sklearn_classifier() if self._learner is not None else None
learner = self.learner._get_sklearn_classifier() if self.learner is not None else None
return sk_AdaBoostClassifier(
estimator=learner,
n_estimators=self._maximum_number_of_learners,
n_estimators=self.maximum_number_of_learners,
learning_rate=self._learning_rate,
)
8 changes: 8 additions & 0 deletions src/safeds/ml/classical/classification/_gradient_boosting.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ def __init__(self, *, number_of_trees: int = 100, learning_rate: float = 0.1) ->
self._feature_names: list[str] | None = None
self._target_name: str | None = None

@property
def number_of_trees(self) -> int:
return self._number_of_trees

@property
def learning_rate(self) -> float:
return self._learning_rate

def fit(self, training_set: TaggedTable) -> GradientBoosting:
"""
Create a copy of this classifier and fit it with the given training data.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ def __init__(self, number_of_neighbors: int) -> None:
self._feature_names: list[str] | None = None
self._target_name: str | None = None

@property
def number_of_neighbors(self) -> int:
return self._number_of_neighbors

def fit(self, training_set: TaggedTable) -> KNearestNeighbors:
"""
Create a copy of this classifier and fit it with the given training data.
Expand Down
4 changes: 4 additions & 0 deletions src/safeds/ml/classical/classification/_random_forest.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ def __init__(self, *, number_of_trees: int = 100) -> None:
self._feature_names: list[str] | None = None
self._target_name: str | None = None

@property
def number_of_trees(self) -> int:
return self._number_of_trees

def fit(self, training_set: TaggedTable) -> RandomForest:
"""
Create a copy of this classifier and fit it with the given training data.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,15 @@ def __init__(self, *, c: float = 1.0) -> None:
self._feature_names: list[str] | None = None
self._target_name: str | None = None

# Hyperparameters
if c <= 0:
raise ValueError("The parameter 'c' has to be strictly positive.")
self._c = c

@property
def c(self) -> float:
return self._c

def fit(self, training_set: TaggedTable) -> SupportVectorMachine:
"""
Create a copy of this classifier and fit it with the given training data.
Expand Down
12 changes: 12 additions & 0 deletions src/safeds/ml/classical/regression/_ada_boost.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,18 @@ def __init__(
self._feature_names: list[str] | None = None
self._target_name: str | None = None

@property
def learner(self) -> Regressor | None:
return self._learner

@property
def maximum_number_of_learners(self) -> int:
return self._maximum_number_of_learners

@property
def learning_rate(self) -> float:
return self._learning_rate

def fit(self, training_set: TaggedTable) -> AdaBoost:
"""
Create a copy of this regressor and fit it with the given training data.
Expand Down
8 changes: 8 additions & 0 deletions src/safeds/ml/classical/regression/_elastic_net_regression.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,14 @@ def __init__(self, *, alpha: float = 1.0, lasso_ratio: float = 0.5) -> None:
self._feature_names: list[str] | None = None
self._target_name: str | None = None

@property
def alpha(self) -> float:
return self._alpha

@property
def lasso_ratio(self) -> float:
return self._lasso_ratio

def fit(self, training_set: TaggedTable) -> ElasticNetRegression:
"""
Create a copy of this regressor and fit it with the given training data.
Expand Down
8 changes: 8 additions & 0 deletions src/safeds/ml/classical/regression/_gradient_boosting.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ def __init__(self, *, number_of_trees: int = 100, learning_rate: float = 0.1) ->
self._feature_names: list[str] | None = None
self._target_name: str | None = None

@property
def number_of_trees(self) -> int:
return self._number_of_trees

@property
def learning_rate(self) -> float:
return self._learning_rate

def fit(self, training_set: TaggedTable) -> GradientBoosting:
"""
Create a copy of this regressor and fit it with the given training data.
Expand Down
4 changes: 4 additions & 0 deletions src/safeds/ml/classical/regression/_k_nearest_neighbors.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ def __init__(self, number_of_neighbors: int) -> None:
self._feature_names: list[str] | None = None
self._target_name: str | None = None

@property
def number_of_neighbors(self) -> int:
return self._number_of_neighbors

def fit(self, training_set: TaggedTable) -> KNearestNeighbors:
"""
Create a copy of this regressor and fit it with the given training data.
Expand Down
4 changes: 4 additions & 0 deletions src/safeds/ml/classical/regression/_lasso_regression.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ def __init__(self, *, alpha: float = 1.0) -> None:
self._feature_names: list[str] | None = None
self._target_name: str | None = None

@property
def alpha(self) -> float:
return self._alpha

def fit(self, training_set: TaggedTable) -> LassoRegression:
"""
Create a copy of this regressor and fit it with the given training data.
Expand Down
4 changes: 4 additions & 0 deletions src/safeds/ml/classical/regression/_random_forest.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ def __init__(self, *, number_of_trees: int = 100) -> None:
self._feature_names: list[str] | None = None
self._target_name: str | None = None

@property
def number_of_trees(self) -> int:
return self._number_of_trees

def fit(self, training_set: TaggedTable) -> RandomForest:
"""
Create a copy of this regressor and fit it with the given training data.
Expand Down
4 changes: 4 additions & 0 deletions src/safeds/ml/classical/regression/_ridge_regression.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ def __init__(self, *, alpha: float = 1.0) -> None:
self._feature_names: list[str] | None = None
self._target_name: str | None = None

@property
def alpha(self) -> float:
return self._alpha

def fit(self, training_set: TaggedTable) -> RidgeRegression:
"""
Create a copy of this regressor and fit it with the given training data.
Expand Down
5 changes: 5 additions & 0 deletions src/safeds/ml/classical/regression/_support_vector_machine.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,15 @@ def __init__(self, *, c: float = 1.0) -> None:
self._feature_names: list[str] | None = None
self._target_name: str | None = None

# Hyperparameters
if c <= 0:
raise ValueError("The parameter 'c' has to be strictly positive.")
self._c = c

@property
def c(self) -> float:
return self._c

def fit(self, training_set: TaggedTable) -> SupportVectorMachine:
"""
Create a copy of this regressor and fit it with the given training data.
Expand Down
6 changes: 3 additions & 3 deletions tests/safeds/ml/classical/classification/test_ada_boost.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class TestLearner:
def test_should_be_passed_to_fitted_model(self, training_set: TaggedTable) -> None:
learner = AdaBoost()
fitted_model = AdaBoost(learner=learner).fit(training_set)
assert fitted_model._learner == learner
assert fitted_model.learner == learner

def test_should_be_passed_to_sklearn(self, training_set: TaggedTable) -> None:
learner = AdaBoost()
Expand All @@ -25,7 +25,7 @@ def test_should_be_passed_to_sklearn(self, training_set: TaggedTable) -> None:
class TestMaximumNumberOfLearners:
def test_should_be_passed_to_fitted_model(self, training_set: TaggedTable) -> None:
fitted_model = AdaBoost(maximum_number_of_learners=2).fit(training_set)
assert fitted_model._maximum_number_of_learners == 2
assert fitted_model.maximum_number_of_learners == 2

def test_should_be_passed_to_sklearn(self, training_set: TaggedTable) -> None:
fitted_model = AdaBoost(maximum_number_of_learners=2).fit(training_set)
Expand All @@ -40,7 +40,7 @@ def test_should_raise_if_less_than_or_equal_to_0(self) -> None:
class TestLearningRate:
def test_should_be_passed_to_fitted_model(self, training_set: TaggedTable) -> None:
fitted_model = AdaBoost(learning_rate=2).fit(training_set)
assert fitted_model._learning_rate == 2
assert fitted_model.learning_rate == 2

def test_should_be_passed_to_sklearn(self, training_set: TaggedTable) -> None:
fitted_model = AdaBoost(learning_rate=2).fit(training_set)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def training_set() -> TaggedTable:
class TestNumberOfTrees:
def test_should_be_passed_to_fitted_model(self, training_set: TaggedTable) -> None:
fitted_model = GradientBoosting(number_of_trees=2).fit(training_set)
assert fitted_model._number_of_trees == 2
assert fitted_model.number_of_trees == 2

def test_should_be_passed_to_sklearn(self, training_set: TaggedTable) -> None:
fitted_model = GradientBoosting(number_of_trees=2).fit(training_set)
Expand All @@ -27,7 +27,7 @@ def test_should_raise_if_less_than_1(self) -> None:
class TestLearningRate:
def test_should_be_passed_to_fitted_model(self, training_set: TaggedTable) -> None:
fitted_model = GradientBoosting(learning_rate=2).fit(training_set)
assert fitted_model._learning_rate == 2
assert fitted_model.learning_rate == 2

def test_should_be_passed_to_sklearn(self, training_set: TaggedTable) -> None:
fitted_model = GradientBoosting(learning_rate=2).fit(training_set)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def training_set() -> TaggedTable:
class TestNumberOfNeighbors:
def test_should_be_passed_to_fitted_model(self, training_set: TaggedTable) -> None:
fitted_model = KNearestNeighbors(number_of_neighbors=2).fit(training_set)
assert fitted_model._number_of_neighbors == 2
assert fitted_model.number_of_neighbors == 2

def test_should_be_passed_to_sklearn(self, training_set: TaggedTable) -> None:
fitted_model = KNearestNeighbors(number_of_neighbors=2).fit(training_set)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def training_set() -> TaggedTable:
class TestNumberOfTrees:
def test_should_be_passed_to_fitted_model(self, training_set: TaggedTable) -> None:
fitted_model = RandomForest(number_of_trees=2).fit(training_set)
assert fitted_model._number_of_trees == 2
assert fitted_model.number_of_trees == 2

def test_should_be_passed_to_sklearn(self, training_set: TaggedTable) -> None:
fitted_model = RandomForest(number_of_trees=2).fit(training_set)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def training_set() -> TaggedTable:
class TestC:
def test_should_be_passed_to_fitted_model(self, training_set: TaggedTable) -> None:
fitted_model = SupportVectorMachine(c=2).fit(training_set=training_set)
assert fitted_model._c == 2
assert fitted_model.c == 2

def test_should_be_passed_to_sklearn(self, training_set: TaggedTable) -> None:
fitted_model = SupportVectorMachine(c=2).fit(training_set)
Expand Down
6 changes: 3 additions & 3 deletions tests/safeds/ml/classical/regression/test_ada_boost.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class TestLearner:
def test_should_be_passed_to_fitted_model(self, training_set: TaggedTable) -> None:
learner = AdaBoost()
fitted_model = AdaBoost(learner=learner).fit(training_set)
assert fitted_model._learner == learner
assert fitted_model.learner == learner

def test_should_be_passed_to_sklearn(self, training_set: TaggedTable) -> None:
learner = AdaBoost()
Expand All @@ -25,7 +25,7 @@ def test_should_be_passed_to_sklearn(self, training_set: TaggedTable) -> None:
class TestMaximumNumberOfLearners:
def test_should_be_passed_to_fitted_model(self, training_set: TaggedTable) -> None:
fitted_model = AdaBoost(maximum_number_of_learners=2).fit(training_set)
assert fitted_model._maximum_number_of_learners == 2
assert fitted_model.maximum_number_of_learners == 2

def test_should_be_passed_to_sklearn(self, training_set: TaggedTable) -> None:
fitted_model = AdaBoost(maximum_number_of_learners=2).fit(training_set)
Expand All @@ -40,7 +40,7 @@ def test_should_raise_if_less_than_or_equal_to_0(self) -> None:
class TestLearningRate:
def test_should_be_passed_to_fitted_model(self, training_set: TaggedTable) -> None:
fitted_model = AdaBoost(learning_rate=2).fit(training_set)
assert fitted_model._learning_rate == 2
assert fitted_model.learning_rate == 2

def test_should_be_passed_to_sklearn(self, training_set: TaggedTable) -> None:
fitted_model = AdaBoost(learning_rate=2).fit(training_set)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def training_set() -> TaggedTable:
class TestAlpha:
def test_should_be_passed_to_fitted_model(self, training_set: TaggedTable) -> None:
fitted_model = ElasticNetRegression(alpha=1).fit(training_set)
assert fitted_model._alpha == 1
assert fitted_model.alpha == 1

def test_should_be_passed_to_sklearn(self, training_set: TaggedTable) -> None:
fitted_model = ElasticNetRegression(alpha=1).fit(training_set)
Expand All @@ -37,7 +37,7 @@ def test_should_warn_if_equal_to_0(self) -> None:
class TestLassoRatio:
def test_should_be_passed_to_fitted_model(self, training_set: TaggedTable) -> None:
fitted_model = ElasticNetRegression(lasso_ratio=0.3).fit(training_set)
assert fitted_model._lasso_ratio == 0.3
assert fitted_model.lasso_ratio == 0.3

def test_should_be_passed_to_sklearn(self, training_set: TaggedTable) -> None:
fitted_model = ElasticNetRegression(lasso_ratio=0.3).fit(training_set)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def training_set() -> TaggedTable:
class TestNumberOfTrees:
def test_should_be_passed_to_fitted_model(self, training_set: TaggedTable) -> None:
fitted_model = GradientBoosting(number_of_trees=2).fit(training_set)
assert fitted_model._number_of_trees == 2
assert fitted_model.number_of_trees == 2

def test_should_be_passed_to_sklearn(self, training_set: TaggedTable) -> None:
fitted_model = GradientBoosting(number_of_trees=2).fit(training_set)
Expand All @@ -27,7 +27,7 @@ def test_should_raise_if_less_than_1(self) -> None:
class TestLearningRate:
def test_should_be_passed_to_fitted_model(self, training_set: TaggedTable) -> None:
fitted_model = GradientBoosting(learning_rate=2).fit(training_set)
assert fitted_model._learning_rate == 2
assert fitted_model.learning_rate == 2

def test_should_be_passed_to_sklearn(self, training_set: TaggedTable) -> None:
fitted_model = GradientBoosting(learning_rate=2).fit(training_set)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def training_set() -> TaggedTable:
class TestNumberOfNeighbors:
def test_should_be_passed_to_fitted_model(self, training_set: TaggedTable) -> None:
fitted_model = KNearestNeighbors(number_of_neighbors=2).fit(training_set)
assert fitted_model._number_of_neighbors == 2
assert fitted_model.number_of_neighbors == 2

def test_should_be_passed_to_sklearn(self, training_set: TaggedTable) -> None:
fitted_model = KNearestNeighbors(number_of_neighbors=2).fit(training_set)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def training_set() -> TaggedTable:
class TestAlpha:
def test_should_be_passed_to_fitted_model(self, training_set: TaggedTable) -> None:
fitted_model = LassoRegression(alpha=1).fit(training_set)
assert fitted_model._alpha == 1
assert fitted_model.alpha == 1

def test_should_be_passed_to_sklearn(self, training_set: TaggedTable) -> None:
fitted_model = LassoRegression(alpha=1).fit(training_set)
Expand Down
2 changes: 1 addition & 1 deletion tests/safeds/ml/classical/regression/test_random_forest.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def training_set() -> TaggedTable:
class TestNumberOfTrees:
def test_should_be_passed_to_fitted_model(self, training_set: TaggedTable) -> None:
fitted_model = RandomForest(number_of_trees=2).fit(training_set)
assert fitted_model._number_of_trees == 2
assert fitted_model.number_of_trees == 2

def test_should_be_passed_to_sklearn(self, training_set: TaggedTable) -> None:
fitted_model = RandomForest(number_of_trees=2).fit(training_set)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def training_set() -> TaggedTable:
class TestAlpha:
def test_should_be_passed_to_fitted_model(self, training_set: TaggedTable) -> None:
fitted_model = RidgeRegression(alpha=1).fit(training_set)
assert fitted_model._alpha == 1
assert fitted_model.alpha == 1

def test_should_be_passed_to_sklearn(self, training_set: TaggedTable) -> None:
fitted_model = RidgeRegression(alpha=1).fit(training_set)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def training_set() -> TaggedTable:
class TestC:
def test_should_be_passed_to_fitted_model(self, training_set: TaggedTable) -> None:
fitted_model = SupportVectorMachine(c=2).fit(training_set=training_set)
assert fitted_model._c == 2
assert fitted_model.c == 2

def test_should_be_passed_to_sklearn(self, training_set: TaggedTable) -> None:
fitted_model = SupportVectorMachine(c=2).fit(training_set)
Expand Down

0 comments on commit 5c7a662

Please sign in to comment.