OptCV.__init__()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 16
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 14
dl 0
loc 16
rs 9.7
c 0
b 0
f 0
cc 1
nop 7
1
"""opt_cv module for Hyperactive optimization."""
2
3
from collections.abc import Callable
4
from typing import Union
5
6
from sklearn.base import BaseEstimator, clone
7
8
from hyperactive.experiment.integrations.sklearn_cv import SklearnCvExperiment
9
from hyperactive.integrations.sklearn.best_estimator import (
10
    BestEstimator as _BestEstimator_,
11
)
12
from hyperactive.integrations.sklearn.checks import Checks
13
14
from ._compat import _check_method_params, _safe_refit, _safe_validate_X_y
15
16
17
class OptCV(BaseEstimator, _BestEstimator_, Checks):
18
    """Tuning via any optimizer in the hyperactive API.
19
20
    Parameters
21
    ----------
22
    estimator : SklearnBaseEstimator
23
        The estimator to be tuned.
24
    optimizer : hyperactive BaseOptimizer
25
        The optimizer to be used for hyperparameter search.
26
    scoring : callable or str, default = accuracy_score or mean_squared_error
27
        sklearn scoring function or metric to evaluate the model's performance.
28
        Default is determined by the type of estimator:
29
        ``accuracy_score`` for classifiers, and
30
        ``mean_squared_error`` for regressors, as per sklearn convention
31
        through the default ``score`` method of the estimator.
32
    refit: bool, optional, default = True
33
        Whether to refit the best estimator with the entire dataset.
34
        If True, the best estimator is refit with the entire dataset after
35
        the optimization process.
36
        If False, does not refit, and predict is not available.
37
    cv : int or cross-validation generator, default = KFold(n_splits=3, shuffle=True)
38
        The number of folds or cross-validation strategy to be used.
39
        If int, the cross-validation used is KFold(n_splits=cv, shuffle=True).
40
41
    Example
42
    -------
43
    Tuning sklearn SVC via grid search
44
45
    1. defining the tuned estimator:
46
    >>> from sklearn.svm import SVC
47
    >>> from hyperactive.integrations.sklearn import OptCV
48
    >>> from hyperactive.opt import GridSearchSk as GridSearch
49
    >>>
50
    >>> param_grid = {"kernel": ["linear", "rbf"], "C": [1, 10]}
51
    >>> tuned_svc = OptCV(SVC(), GridSearch(param_grid))
52
53
    2. fitting the tuned estimator:
54
    >>> from sklearn.datasets import load_iris
55
    >>> from sklearn.model_selection import train_test_split
56
    >>> X, y = load_iris(return_X_y=True)
57
    >>> X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
58
    >>>
59
    >>> tuned_svc.fit(X_train, y_train)
60
    OptCV(...)
61
    >>> y_pred = tuned_svc.predict(X_test)
62
63
    3. obtaining best parameters and best estimator
64
    >>> best_params = tuned_svc.best_params_
65
    >>> best_estimator = tuned_svc.best_estimator_
66
    """
67
68
    _required_parameters = ["estimator", "optimizer"]
69
70
    def __init__(
71
        self,
72
        estimator,
73
        optimizer,
74
        *,
75
        scoring: Union[Callable, str, None] = None,
76
        refit: bool = True,
77
        cv=None,
78
    ):
79
        super().__init__()
80
81
        self.estimator = estimator
82
        self.optimizer = optimizer
83
        self.scoring = scoring
84
        self.refit = refit
85
        self.cv = cv
86
87
    def _refit(self, X, y=None, **fit_params):
88
        self.best_estimator_ = clone(self.estimator).set_params(
89
            **clone(self.best_params_, safe=False)
90
        )
91
92
        self.best_estimator_.fit(X, y, **fit_params)
93
        return self
94
95
    def _check_data(self, X, y):
96
        return _safe_validate_X_y(self, X, y)
97
98
    @Checks.verify_fit
99
    def fit(self, X, y, **fit_params):
100
        """Fit the model.
101
102
        Parameters
103
        ----------
104
        X : {array-like, sparse matrix} of shape (n_samples, n_features)
105
            Training data.
106
107
        y : array-like of shape (n_samples,) or (n_samples, n_targets)
108
            Target values. Will be cast to X's dtype if necessary.
109
110
        Returns
111
        -------
112
        self : object
113
            Fitted Estimator.
114
        """
115
        X, y = self._check_data(X, y)
116
117
        fit_params = _check_method_params(X, params=fit_params)
118
119
        experiment = SklearnCvExperiment(
120
            estimator=self.estimator,
121
            scoring=self.scoring,
122
            cv=self.cv,
123
            X=X,
124
            y=y,
125
        )
126
        self.scorer_ = experiment.scorer_
127
128
        optimizer = self.optimizer.clone()
129
        optimizer.set_params(experiment=experiment)
130
        best_params = optimizer.solve()
131
132
        self.best_params_ = best_params
133
        self.best_estimator_ = clone(self.estimator).set_params(**best_params)
134
135
        _safe_refit(self, X, y, fit_params)
136
137
        return self
138
139
    def score(self, X, y=None, **params):
140
        """Return the score on the given data, if the estimator has been refit.
141
142
        This uses the score defined by ``scoring`` where provided, and the
143
        ``best_estimator_.score`` method otherwise.
144
145
        Parameters
146
        ----------
147
        X : array-like of shape (n_samples, n_features)
148
            Input data, where `n_samples` is the number of samples and
149
            `n_features` is the number of features.
150
151
        y : array-like of shape (n_samples, n_output) \
152
            or (n_samples,), default=None
153
            Target relative to X for classification or regression;
154
            None for unsupervised learning.
155
156
        **params : dict
157
            Parameters to be passed to the underlying scorer(s).
158
159
        Returns
160
        -------
161
        score : float
162
            The score defined by ``scoring`` if provided, and the
163
            ``best_estimator_.score`` method otherwise.
164
        """
165
        return self.scorer_(self.best_estimator_, X, y, **params)
166
167
    @property
168
    def fit_successful(self):
169
        """Fit Successful function."""
170
        self._fit_successful
171