From 83d1c677142378af9ce080cff5788d6426b3c115 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Kir=C3=A1ly?= Date: Sat, 14 Jun 2025 14:52:21 +0200 Subject: [PATCH 1/9] Update best_estimator.py --- src/hyperactive/integrations/sklearn/best_estimator.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/hyperactive/integrations/sklearn/best_estimator.py b/src/hyperactive/integrations/sklearn/best_estimator.py index def5f828..ec317596 100644 --- a/src/hyperactive/integrations/sklearn/best_estimator.py +++ b/src/hyperactive/integrations/sklearn/best_estimator.py @@ -5,7 +5,6 @@ from sklearn.utils.metaestimators import available_if from sklearn.utils.deprecation import _deprecate_Xt_in_inverse_transform -from sklearn.exceptions import NotFittedError from sklearn.utils.validation import check_is_fitted from .utils import _estimator_has @@ -47,8 +46,7 @@ def transform(self, X): return self.best_estimator_.transform(X) @available_if(_estimator_has("inverse_transform")) - def inverse_transform(self, X=None, Xt=None): - X = _deprecate_Xt_in_inverse_transform(X, Xt) + def inverse_transform(self, X=None): check_is_fitted(self) return self.best_estimator_.inverse_transform(X) From 29f3e1bb2d42d8c2528c05838031164372afb0d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Kir=C3=A1ly?= Date: Sat, 14 Jun 2025 15:02:51 +0200 Subject: [PATCH 2/9] Update best_estimator.py --- src/hyperactive/integrations/sklearn/best_estimator.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/hyperactive/integrations/sklearn/best_estimator.py b/src/hyperactive/integrations/sklearn/best_estimator.py index ec317596..b248ec87 100644 --- a/src/hyperactive/integrations/sklearn/best_estimator.py +++ b/src/hyperactive/integrations/sklearn/best_estimator.py @@ -4,7 +4,6 @@ from sklearn.utils.metaestimators import available_if -from sklearn.utils.deprecation import _deprecate_Xt_in_inverse_transform from sklearn.utils.validation import check_is_fitted from .utils import _estimator_has From 48ef77bc30d6a0d37af299e67532381a635c4eb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Kir=C3=A1ly?= Date: Sat, 14 Jun 2025 15:53:01 +0200 Subject: [PATCH 3/9] sklearn attempted fix --- .../integrations/sklearn/_adapter/__init__.py | 8 +++++ .../sklearn/_adapter/_sklearnadapter.py | 30 +++++++++++++++++++ .../sklearn/hyperactive_search_cv.py | 3 +- .../integrations/sklearn/opt_cv.py | 3 +- 4 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 src/hyperactive/integrations/sklearn/_adapter/__init__.py create mode 100644 src/hyperactive/integrations/sklearn/_adapter/_sklearnadapter.py diff --git a/src/hyperactive/integrations/sklearn/_adapter/__init__.py b/src/hyperactive/integrations/sklearn/_adapter/__init__.py new file mode 100644 index 00000000..c5ebd29a --- /dev/null +++ b/src/hyperactive/integrations/sklearn/_adapter/__init__.py @@ -0,0 +1,8 @@ +# copyright: hyperactive developers, MIT License (see LICENSE file) + + +from hyperactive.integrations.sklearn._adapter._sklearnadapter import _SklearnAdapter + +__all__ = [ + "_SklearnAdapter", +] diff --git a/src/hyperactive/integrations/sklearn/_adapter/_sklearnadapter.py b/src/hyperactive/integrations/sklearn/_adapter/_sklearnadapter.py new file mode 100644 index 00000000..95e07ebd --- /dev/null +++ b/src/hyperactive/integrations/sklearn/_adapter/_sklearnadapter.py @@ -0,0 +1,30 @@ +"""Adapter for sklearn regressors and classifiers for Hyperactive optimizers.""" + +from sklearn.base import clone +from sklearn.utils.validation import indexable, _check_method_params + + +class _SklearnAdapter: + + _required_parameters = ["estimator", "optimizer", "params_config"] + + 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 _check_data(self, X, y): + X, y = indexable(X, y) + if hasattr(self, "_validate_data"): + validate_data = self._validate_data + else: + from sklearn.utils.validation import validate_data + + return validate_data(X, y, ensure_2d=False) + + @property + def fit_successful(self): + self._fit_successful diff --git a/src/hyperactive/integrations/sklearn/hyperactive_search_cv.py b/src/hyperactive/integrations/sklearn/hyperactive_search_cv.py index 2acb414f..469f119a 100644 --- a/src/hyperactive/integrations/sklearn/hyperactive_search_cv.py +++ b/src/hyperactive/integrations/sklearn/hyperactive_search_cv.py @@ -17,9 +17,10 @@ from .checks import Checks from ...optimizers import RandomSearchOptimizer from hyperactive.experiment.integrations.sklearn_cv import SklearnCvExperiment +from hyperactive.integrations.sklearn._adapter import _SklearnAdapter -class HyperactiveSearchCV(BaseEstimator, _BestEstimator_, Checks): +class HyperactiveSearchCV(_SklearnAdapter, BaseEstimator, _BestEstimator_, Checks): """ HyperactiveSearchCV class for hyperparameter tuning using cross-validation with sklearn estimators. diff --git a/src/hyperactive/integrations/sklearn/opt_cv.py b/src/hyperactive/integrations/sklearn/opt_cv.py index eb83cf90..bf5d816a 100644 --- a/src/hyperactive/integrations/sklearn/opt_cv.py +++ b/src/hyperactive/integrations/sklearn/opt_cv.py @@ -10,10 +10,11 @@ from hyperactive.integrations.sklearn.best_estimator import ( BestEstimator as _BestEstimator_ ) +from hyperactive.integrations.sklearn._adapter import _SklearnAdapter from hyperactive.integrations.sklearn.checks import Checks -class OptCV(BaseEstimator, _BestEstimator_, Checks): +class OptCV(_SklearnAdapter, BaseEstimator, _BestEstimator_, Checks): """Tuning via any optimizer in the hyperactive API. Parameters From 4018e99be484e7745a53ed66372fa3ced0874c1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Kir=C3=A1ly?= Date: Sat, 14 Jun 2025 16:05:37 +0200 Subject: [PATCH 4/9] Update _sklearnadapter.py --- .../integrations/sklearn/_adapter/_sklearnadapter.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/hyperactive/integrations/sklearn/_adapter/_sklearnadapter.py b/src/hyperactive/integrations/sklearn/_adapter/_sklearnadapter.py index 95e07ebd..11731889 100644 --- a/src/hyperactive/integrations/sklearn/_adapter/_sklearnadapter.py +++ b/src/hyperactive/integrations/sklearn/_adapter/_sklearnadapter.py @@ -18,6 +18,9 @@ def _refit(self, X, y=None, **fit_params): def _check_data(self, X, y): X, y = indexable(X, y) + if y is not None: + if y.ndim == 1: + y = y.reshape(-1, 1) if hasattr(self, "_validate_data"): validate_data = self._validate_data else: From 4139614759fb0822552291f76079ffc27be9db25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Kir=C3=A1ly?= Date: Sat, 14 Jun 2025 17:43:16 +0200 Subject: [PATCH 5/9] Update _sklearnadapter.py --- .../integrations/sklearn/_adapter/_sklearnadapter.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hyperactive/integrations/sklearn/_adapter/_sklearnadapter.py b/src/hyperactive/integrations/sklearn/_adapter/_sklearnadapter.py index 11731889..aec1e5fc 100644 --- a/src/hyperactive/integrations/sklearn/_adapter/_sklearnadapter.py +++ b/src/hyperactive/integrations/sklearn/_adapter/_sklearnadapter.py @@ -18,9 +18,9 @@ def _refit(self, X, y=None, **fit_params): def _check_data(self, X, y): X, y = indexable(X, y) - if y is not None: - if y.ndim == 1: - y = y.reshape(-1, 1) + if X is not None: + if X.ndim == 1: + X = X.reshape(-1, 1) if hasattr(self, "_validate_data"): validate_data = self._validate_data else: From 672b40c88ec7ae5595a3369b97b64f9c9e6e0017 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Kir=C3=A1ly?= Date: Sat, 14 Jun 2025 17:53:07 +0200 Subject: [PATCH 6/9] fix --- .../sklearn/_adapter/_sklearnadapter.py | 3 --- .../sklearn/hyperactive_search_cv.py | 17 ----------------- src/hyperactive/integrations/sklearn/opt_cv.py | 17 ----------------- 3 files changed, 37 deletions(-) diff --git a/src/hyperactive/integrations/sklearn/_adapter/_sklearnadapter.py b/src/hyperactive/integrations/sklearn/_adapter/_sklearnadapter.py index aec1e5fc..95e07ebd 100644 --- a/src/hyperactive/integrations/sklearn/_adapter/_sklearnadapter.py +++ b/src/hyperactive/integrations/sklearn/_adapter/_sklearnadapter.py @@ -18,9 +18,6 @@ def _refit(self, X, y=None, **fit_params): def _check_data(self, X, y): X, y = indexable(X, y) - if X is not None: - if X.ndim == 1: - X = X.reshape(-1, 1) if hasattr(self, "_validate_data"): validate_data = self._validate_data else: diff --git a/src/hyperactive/integrations/sklearn/hyperactive_search_cv.py b/src/hyperactive/integrations/sklearn/hyperactive_search_cv.py index 469f119a..58f51ea7 100644 --- a/src/hyperactive/integrations/sklearn/hyperactive_search_cv.py +++ b/src/hyperactive/integrations/sklearn/hyperactive_search_cv.py @@ -78,23 +78,6 @@ def __init__( self.refit = refit self.cv = cv - 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 _check_data(self, X, y): - X, y = indexable(X, y) - if hasattr(self, "_validate_data"): - validate_data = self._validate_data - else: - from sklearn.utils.validation import validate_data - - return validate_data(X, y) - @Checks.verify_fit def fit(self, X, y, **fit_params): """ diff --git a/src/hyperactive/integrations/sklearn/opt_cv.py b/src/hyperactive/integrations/sklearn/opt_cv.py index bf5d816a..34b34452 100644 --- a/src/hyperactive/integrations/sklearn/opt_cv.py +++ b/src/hyperactive/integrations/sklearn/opt_cv.py @@ -84,23 +84,6 @@ def __init__( self.refit = refit self.cv = cv - 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 _check_data(self, X, y): - X, y = indexable(X, y) - if hasattr(self, "_validate_data"): - validate_data = self._validate_data - else: - from sklearn.utils.validation import validate_data - - return validate_data(X, y) - @Checks.verify_fit def fit(self, X, y, **fit_params): """Fit the model. From cefa2aafd3a41b6c1fe481f045b8278d0347b4e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Kir=C3=A1ly?= Date: Sat, 14 Jun 2025 18:01:49 +0200 Subject: [PATCH 7/9] Update _sklearnadapter.py --- .../integrations/sklearn/_adapter/_sklearnadapter.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hyperactive/integrations/sklearn/_adapter/_sklearnadapter.py b/src/hyperactive/integrations/sklearn/_adapter/_sklearnadapter.py index 95e07ebd..96b0c0fd 100644 --- a/src/hyperactive/integrations/sklearn/_adapter/_sklearnadapter.py +++ b/src/hyperactive/integrations/sklearn/_adapter/_sklearnadapter.py @@ -18,12 +18,14 @@ def _refit(self, X, y=None, **fit_params): def _check_data(self, X, y): X, y = indexable(X, y) + if hasattr(X, "ndim") and X.ndim == 1: + X = X.reshape(-1, 1) if hasattr(self, "_validate_data"): validate_data = self._validate_data else: from sklearn.utils.validation import validate_data - return validate_data(X, y, ensure_2d=False) + return validate_data(X, y) @property def fit_successful(self): From e07f0652c33e3671f3962dd099db0813ad7b44da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Kir=C3=A1ly?= Date: Sat, 14 Jun 2025 18:55:25 +0200 Subject: [PATCH 8/9] Update pyproject.toml --- pyproject.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 9ffa4744..b165a184 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -42,11 +42,12 @@ dependencies = [ "pandas <3.0.0", "gradient-free-optimizers >=1.2.4, <2.0.0", "scikit-base <1.0.0", + "scikit-learn <1.7.0", ] [project.optional-dependencies] sklearn-integration = [ - "scikit-learn == 1.6.1", + "scikit-learn <1.7.0", ] build = [ "setuptools", From dc1032fd14534f4259739bd7066e8581a53e2145 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Kir=C3=A1ly?= Date: Sat, 14 Jun 2025 19:17:15 +0200 Subject: [PATCH 9/9] Update pyproject.toml --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index b165a184..54ec7b9b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -42,12 +42,12 @@ dependencies = [ "pandas <3.0.0", "gradient-free-optimizers >=1.2.4, <2.0.0", "scikit-base <1.0.0", - "scikit-learn <1.7.0", + "scikit-learn <1.8.0", ] [project.optional-dependencies] sklearn-integration = [ - "scikit-learn <1.7.0", + "scikit-learn <1.8.0", ] build = [ "setuptools",