From 1b772ff31a6d0a517dd4a1252f3b2603d24c39a6 Mon Sep 17 00:00:00 2001 From: Simon Blanke Date: Tue, 27 Aug 2024 11:15:25 +0200 Subject: [PATCH 1/2] add best_params_ and best_score_ attributes and pass it to best_estimator_ --- .../sklearn/hyperactive_search_cv.py | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/hyperactive/integrations/sklearn/hyperactive_search_cv.py b/src/hyperactive/integrations/sklearn/hyperactive_search_cv.py index 179ee389..53db9491 100644 --- a/src/hyperactive/integrations/sklearn/hyperactive_search_cv.py +++ b/src/hyperactive/integrations/sklearn/hyperactive_search_cv.py @@ -40,21 +40,19 @@ def __init__( self.refit = refit self.cv = cv - def _refit( - self, - X, - y=None, - **fit_params, - ): - self.best_estimator_ = clone(self.estimator) + def _refit(self, X, y=None, **fit_params): + self.best_estimator_ = clone(self.estimator).set_params( + **clone(self.best_params_, safe=False) + ) + self.best_estimator_.fit(X, y, **fit_params) return self - def fit(self, X, y, **params): + def fit(self, X, y, **fit_params): X, y = indexable(X, y) X, y = self._validate_data(X, y) - params = _check_method_params(X, params=params) + params = _check_method_params(X, params=fit_params) self.scorer_ = check_scoring(self.estimator, scoring=self.scoring) objective_function_adapter = ObjectiveFunctionAdapter( @@ -62,10 +60,11 @@ def fit(self, X, y, **params): ) objective_function_adapter.add_dataset(X, y) objective_function_adapter.add_validation(self.scorer_, self.cv) + objective_function = objective_function_adapter.objective_function hyper = Hyperactive(verbosity=False) hyper.add_search( - objective_function_adapter.objective_function, + objective_function, search_space=self.params_config, optimizer=self.optimizer, n_iter=self.n_iter, @@ -73,9 +72,11 @@ def fit(self, X, y, **params): random_state=self.random_state, ) hyper.run() + self.best_params_ = hyper.best_para(objective_function) + self.best_score_ = hyper.best_score(objective_function) if self.refit: - self._refit(X, y, **params) + self._refit(X, y, **fit_params) return self From 160e668cd3fba21380432a17207715fc5e508e9c Mon Sep 17 00:00:00 2001 From: Simon Blanke Date: Tue, 27 Aug 2024 11:15:44 +0200 Subject: [PATCH 2/2] fix tests + add tests for best params and score --- .../integrations/sklearn/test_sklearn_api.py | 49 ++++++++++++------- 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/tests/integrations/sklearn/test_sklearn_api.py b/tests/integrations/sklearn/test_sklearn_api.py index 6e11fd66..0cc4b447 100644 --- a/tests/integrations/sklearn/test_sklearn_api.py +++ b/tests/integrations/sklearn/test_sklearn_api.py @@ -3,7 +3,6 @@ from sklearn import svm, datasets from sklearn.naive_bayes import GaussianNB -from sklearn.isotonic import IsotonicRegression from sklearn.decomposition import PCA @@ -16,26 +15,27 @@ iris = datasets.load_iris() X, y = iris.data, iris.target - -ir = IsotonicRegression() nb = GaussianNB() svc = svm.SVC() -pca = PCA(n_components=2) +pca = PCA() + +parameters_svc = {"kernel": ["linear", "rbf"], "C": [1, 10]} +parameters_nb = {"var_smoothing": [1e-7, 1e-8, 1e-9]} +parameters_pca = {"n_components": [2, 3, 4]} -parameters = {"kernel": ["linear", "rbf"], "C": [1, 10]} opt = RandomSearchOptimizer() def test_fit(): - search = HyperactiveSearchCV(svc, opt, parameters) + search = HyperactiveSearchCV(svc, opt, parameters_svc) search.fit(X, y) check_is_fitted(search) def test_score(): - search = HyperactiveSearchCV(svc, opt, parameters) + search = HyperactiveSearchCV(svc, opt, parameters_svc) search.fit(X, y) score = search.score(X, y) @@ -43,14 +43,14 @@ def test_score(): def test_classes_(): - search = HyperactiveSearchCV(svc, opt, parameters) + search = HyperactiveSearchCV(svc, opt, parameters_svc) search.fit(X, y) assert [0, 1, 2] == list(search.classes_) def test_score_samples(): - search = HyperactiveSearchCV(svc, opt, parameters) + search = HyperactiveSearchCV(svc, opt, parameters_svc) search.fit(X, y) with pytest.raises(AttributeError): @@ -58,7 +58,7 @@ def test_score_samples(): def test_predict(): - search = HyperactiveSearchCV(svc, opt, parameters) + search = HyperactiveSearchCV(svc, opt, parameters_svc) search.fit(X, y) result = search.predict(X) @@ -66,13 +66,13 @@ def test_predict(): def test_predict_proba(): - search = HyperactiveSearchCV(svc, opt, parameters) + search = HyperactiveSearchCV(svc, opt, parameters_svc) search.fit(X, y) with pytest.raises(AttributeError): search.predict_proba(X) - search = HyperactiveSearchCV(nb, opt, parameters) + search = HyperactiveSearchCV(nb, opt, parameters_nb) search.fit(X, y) result = search.predict(X) @@ -80,13 +80,13 @@ def test_predict_proba(): def test_predict_log_proba(): - search = HyperactiveSearchCV(svc, opt, parameters) + search = HyperactiveSearchCV(svc, opt, parameters_svc) search.fit(X, y) with pytest.raises(AttributeError): search.predict_log_proba(X) - search = HyperactiveSearchCV(nb, opt, parameters) + search = HyperactiveSearchCV(nb, opt, parameters_nb) search.fit(X, y) result = search.predict_log_proba(X) @@ -94,7 +94,7 @@ def test_predict_log_proba(): def test_decision_function(): - search = HyperactiveSearchCV(svc, opt, parameters) + search = HyperactiveSearchCV(svc, opt, parameters_svc) search.fit(X, y) result = search.decision_function(X) @@ -102,13 +102,13 @@ def test_decision_function(): def test_transform(): - search = HyperactiveSearchCV(svc, opt, parameters) + search = HyperactiveSearchCV(svc, opt, parameters_svc) search.fit(X, y) with pytest.raises(AttributeError): search.transform(X) - search = HyperactiveSearchCV(pca, opt, parameters) + search = HyperactiveSearchCV(pca, opt, parameters_pca) search.fit(X, y) result = search.transform(X) @@ -116,14 +116,25 @@ def test_transform(): def test_inverse_transform(): - search = HyperactiveSearchCV(svc, opt, parameters) + search = HyperactiveSearchCV(svc, opt, parameters_svc) search.fit(X, y) with pytest.raises(AttributeError): search.inverse_transform(X) - search = HyperactiveSearchCV(pca, opt, parameters) + search = HyperactiveSearchCV(pca, opt, parameters_pca) search.fit(X, y) result = search.inverse_transform(search.transform(X)) assert isinstance(result, np.ndarray) + + +def test_best_params_and_score(): + search = HyperactiveSearchCV(svc, opt, parameters_svc) + search.fit(X, y) + + best_params = search.best_params_ + best_score = search.best_score_ + + assert "kernel" in best_params and "C" in best_params + assert isinstance(best_score, float)