CmaEsOptimizer.__init__()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 25
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 23
dl 0
loc 25
rs 9.328
c 0
b 0
f 0
cc 1
nop 11

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
"""CMA-ES (Covariance Matrix Adaptation Evolution Strategy) optimizer."""
2
# copyright: hyperactive developers, MIT License (see LICENSE file)
3
4
from .._adapters._base_optuna_adapter import _BaseOptunaAdapter
5
6
7
class CmaEsOptimizer(_BaseOptunaAdapter):
8
    """CMA-ES (Covariance Matrix Adaptation Evolution Strategy) optimizer.
9
10
    Parameters
11
    ----------
12
    param_space : dict[str, tuple or list or optuna distributions]
13
        The search space to explore. Dictionary with parameter names
14
        as keys and either tuples/lists of (low, high) or
15
        optuna distribution objects as values.
16
    n_trials : int, default=100
17
        Number of optimization trials.
18
    initialize : dict[str, int], default=None
19
        The method to generate initial positions. A dictionary with
20
        the following key literals and the corresponding value type:
21
        {"grid": int, "vertices": int, "random": int, "warm_start": list[dict]}
22
    random_state : None, int, default=None
23
        If None, create a new random state. If int, create a new random state
24
        seeded with the value.
25
    early_stopping : int, default=None
26
        Number of trials after which to stop if no improvement.
27
    max_score : float, default=None
28
        Maximum score threshold. Stop optimization when reached.
29
    x0 : dict, default=None
30
        Initial parameter values for CMA-ES.
31
    sigma0 : float, default=1.0
32
        Initial standard deviation for CMA-ES.
33
    n_startup_trials : int, default=1
34
        Number of startup trials for CMA-ES.
35
    experiment : BaseExperiment, optional
36
        The experiment to optimize parameters for.
37
        Optional, can be passed later via ``set_params``.
38
39
    Examples
40
    --------
41
    Basic usage of CmaEsOptimizer with a scikit-learn experiment:
42
43
    >>> from hyperactive.experiment.integrations import SklearnCvExperiment
44
    >>> from hyperactive.opt.optuna import CmaEsOptimizer
45
    >>> from sklearn.datasets import load_iris
46
    >>> from sklearn.svm import SVC
47
    >>> X, y = load_iris(return_X_y=True)
48
    >>> sklearn_exp = SklearnCvExperiment(estimator=SVC(), X=X, y=y)
49
    >>> param_space = {
50
    ...     "C": (0.01, 10),
51
    ...     "gamma": (0.0001, 10),
52
    ... }
53
    >>> optimizer = CmaEsOptimizer(
54
    ...     param_space=param_space, n_trials=50, experiment=sklearn_exp
55
    ... )
56
    >>> best_params = optimizer.solve()
57
    """
58
59
    _tags = {
60
        "info:name": "CMA-ES Optimizer",
61
        "info:local_vs_global": "global",
62
        "info:explore_vs_exploit": "mixed",
63
        "info:compute": "high",
64
        "python_dependencies": ["optuna", "cmaes"],
65
    }
66
67
    def __init__(
68
        self,
69
        param_space=None,
70
        n_trials=100,
71
        initialize=None,
72
        random_state=None,
73
        early_stopping=None,
74
        max_score=None,
75
        x0=None,
76
        sigma0=1.0,
77
        n_startup_trials=1,
78
        experiment=None,
79
    ):
80
        self.x0 = x0
81
        self.sigma0 = sigma0
82
        self.n_startup_trials = n_startup_trials
83
84
        super().__init__(
85
            param_space=param_space,
86
            n_trials=n_trials,
87
            initialize=initialize,
88
            random_state=random_state,
89
            early_stopping=early_stopping,
90
            max_score=max_score,
91
            experiment=experiment,
92
        )
93
94
    def _get_optimizer(self):
95
        """Get the CMA-ES optimizer.
96
97
        Returns
98
        -------
99
        optimizer
100
            The Optuna CmaEsOptimizer instance
101
        """
102
        import optuna
103
104
        try:
105
            import cmaes  # noqa: F401
106
        except ImportError:
107
            raise ImportError(
108
                "CmaEsOptimizer requires the 'cmaes' package. "
109
                "Install it with: pip install cmaes"
110
            )
111
112
        optimizer_kwargs = {
113
            "sigma0": self.sigma0,
114
            "n_startup_trials": self.n_startup_trials,
115
        }
116
117
        if self.x0 is not None:
118
            optimizer_kwargs["x0"] = self.x0
119
120
        if self.random_state is not None:
121
            optimizer_kwargs["seed"] = self.random_state
122
123
        return optuna.samplers.CmaEsSampler(**optimizer_kwargs)
124
125
    @classmethod
126
    def get_test_params(cls, parameter_set="default"):
127
        """Return testing parameter settings for the optimizer."""
128
        from sklearn.datasets import make_regression
129
        from sklearn.neural_network import MLPRegressor
130
131
        from hyperactive.experiment.integrations import SklearnCvExperiment
132
133
        # Test case 1: Basic continuous parameters (from base)
134
        params = super().get_test_params(parameter_set)
135
        params[0].update(
136
            {
137
                "sigma0": 0.5,
138
                "n_startup_trials": 1,
139
            }
140
        )
141
142
        # Test case 2: Neural network with continuous parameters only
143
        # (CMA-ES specific - only continuous parameters allowed)
144
        X, y = make_regression(n_samples=50, n_features=5, noise=0.1, random_state=42)
145
        mlp_exp = SklearnCvExperiment(
146
            estimator=MLPRegressor(random_state=42, max_iter=100), X=X, y=y, cv=3
147
        )
148
149
        continuous_param_space = {
150
            "alpha": (1e-5, 1e-1),  # L2 regularization (continuous)
151
            "learning_rate_init": (1e-4, 1e-1),  # Learning rate (continuous)
152
            "beta_1": (0.8, 0.99),  # Adam beta1 (continuous)
153
            "beta_2": (0.9, 0.999),  # Adam beta2 (continuous)
154
            # Note: No categorical parameters - CMA-ES doesn't support them
155
        }
156
157
        params.append(
158
            {
159
                "param_space": continuous_param_space,
160
                "n_trials": 8,  # Smaller for faster testing
161
                "experiment": mlp_exp,
162
                "sigma0": 0.3,  # Different sigma for diversity
163
                "n_startup_trials": 2,  # More startup trials
164
            }
165
        )
166
167
        # Test case 3: High-dimensional continuous space (CMA-ES strength)
168
        high_dim_continuous = {
169
            f"x{i}": (-1.0, 1.0)
170
            for i in range(6)  # 6D continuous optimization
171
        }
172
173
        params.append(
174
            {
175
                "param_space": high_dim_continuous,
176
                "n_trials": 12,
177
                "experiment": mlp_exp,
178
                "sigma0": 0.7,  # Larger initial spread
179
                "n_startup_trials": 3,
180
            }
181
        )
182
183
        return params
184