Passed
Pull Request — master (#110)
by
unknown
11:00 queued 09:30
created

HillClimbing._run()   A

Complexity

Conditions 1

Size

Total Lines 15
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 10
nop 3
dl 0
loc 15
rs 9.9
c 0
b 0
f 0
1
"""Hill climbing optimizer from gfo."""
2
3
from gradient_free_optimizers import HillClimbingOptimizer
4
from hyperactive.base import BaseOptimizer
5
6
7
class HillClimbing(BaseOptimizer):
8
    """Hill climbing optimizer.
9
10
    Parameters
11
    ----------
12
    experiment : BaseExperiment, optional
13
        The experiment to optimize parameters for.
14
        Optional, can be passed later in ``add_search``.
15
    random_state : None, int, default=None
16
        If None, create a new random state. If int, create a new random state
17
        seeded with the value.
18
    rand_rest_p : float, default=0.1
19
        The probability of a random iteration during the the search process.
20
    epsilon : float, default=0.01
21
        The step-size for the climbing.
22
    distribution : str, default="normal"
23
        The type of distribution to sample from.
24
    n_neighbours : int, default=10
25
        The number of neighbours to sample and evaluate before moving to the best
26
        of those neighbours.
27
    search_space : dict[str, list]
28
        The search space to explore. A dictionary with parameter
29
        names as keys and a numpy array as values.
30
        Optional, can be passed later in ``add_search``.
31
    initialize : dict[str, int], default={"grid": 4, "random": 2, "vertices": 4}
32
        The method to generate initial positions. A dictionary with
33
        the following key literals and the corresponding value type:
34
        {"grid": int, "vertices": int, "random": int, "warm_start": list[dict]}
35
    constraints : list[callable], default=[]
36
        A list of constraints, where each constraint is a callable.
37
        The callable returns `True` or `False` dependend on the input parameters.
38
    n_iter : int, default=100
39
        The number of iterations to run the optimizer.
40
41
    Examples
42
    --------
43
    Hill climbing applied to scikit-learn parameter tuning:
44
45
    1. defining the experiment to optimize:
46
    >>> from hyperactive.experiment.integrations import SklearnCvExperiment
47
    >>> from sklearn.datasets import load_iris
48
    >>> from sklearn.svm import SVC
49
    >>>
50
    >>> X, y = load_iris(return_X_y=True)
51
    >>>
52
    >>> sklearn_exp = SklearnCvExperiment(
53
    ...     estimator=SVC(),
54
    ...     X=X,
55
    ...     y=y,
56
    ... )
57
58
    2. setting up the hill climbing optimizer:
59
    >>> from hyperactive.opt import HillClimbing
60
    >>> import numpy as np
61
    >>> 
62
    >>> hillclimbing_config = {
63
    ...     "search_space": {
64
    ...         "C": np.array([0.01, 0.1, 1, 10]),
65
    ...         "gamma": np.array([0.0001, 0.01, 0.1, 1, 10]),
66
    ...     },
67
    ...     "n_iter": 100,
68
    ... }
69
    >>> hillclimbing = HillClimbing(sklearn_exp, **hillclimbing_config)
70
71
    3. running the hill climbing search:
72
    >>> best_params = hillclimbing.run()
73
74
    Best parameters can also be accessed via the attributes:
75
    >>> best_params = hillclimbing.best_params_
76
    """
77
78
    def __init__(
79
        self,
80
        experiment=None,
81
        random_state=None,
82
        rand_rest_p=0.1,
83
        epsilon=0.01,
84
        distribution="normal",
85
        n_neighbours=10,
86
        search_space=None,
87
        initialize=None,
88
        constraints=None,
89
        n_iter=100,
90
    ):
91
        self.random_state = random_state
92
        self.rand_rest_p = rand_rest_p
93
        self.epsilon = epsilon
94
        self.distribution = distribution
95
        self.n_neighbours = n_neighbours
96
        self.search_space = search_space
97
        self.initialize = initialize
98
        self.constraints = constraints
99
        self.n_iter = n_iter
100
        self.experiment = experiment
101
102
        super().__init__()
103
104
        if initialize is None:
105
            self._initialize = {"grid": 4, "random": 2, "vertices": 4}
106
        else:
107
            self._initialize = initialize
108
109
    def get_search_config(self):
110
        """Get the search configuration.
111
112
        Returns
113
        -------
114
        dict with str keys
115
            The search configuration dictionary.
116
        """
117
        search_config = super().get_search_config()
118
        search_config["initialize"] = self._initialize
119
        return search_config
120
121
    def _run(self, experiment, **search_config):
122
        """Run the optimization search process."""
123
        n_iter = search_config.pop("n_iter", 100)
124
        max_time = search_config.pop("max_time", None)
125
126
        hcopt = HillClimbingOptimizer(**search_config)
127
128
        hcopt.search(
129
            objective_function=experiment.score,
130
            n_iter=n_iter,
131
            max_time=max_time,
132
        )
133
        self.best_params_ = hcopt.best_params()
134
135
        return self.best_params_
136