Skip to content

Commit bb6c6f2

Browse files
Require explicit arguments for mlos_core optimizers (#760)
This is a simple PR that makes all arguments explicit for optimizer-related function calls in preparation to add additional arguments in #751 and make it easier to review. --------- Co-authored-by: Brian Kroth <[email protected]> Co-authored-by: Brian Kroth <[email protected]>
1 parent c7a4823 commit bb6c6f2

File tree

11 files changed

+99
-99
lines changed

11 files changed

+99
-99
lines changed

mlos_bench/mlos_bench/optimizers/mlos_core_optimizer.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ def bulk_register(self,
117117

118118
# TODO: Specify (in the config) which metrics to pass to the optimizer.
119119
# Issue: https://github.com/microsoft/MLOS/issues/745
120-
self._opt.register(df_configs, df_scores[opt_targets].astype(float))
120+
self._opt.register(configs=df_configs, scores=df_scores[opt_targets].astype(float))
121121

122122
if _LOG.isEnabledFor(logging.DEBUG):
123123
(score, _) = self.get_best_observation()
@@ -195,7 +195,7 @@ def register(self, tunables: TunableGroups, status: Status,
195195
_LOG.debug("Score: %s Dataframe:\n%s", registered_score, df_config)
196196
# TODO: Specify (in the config) which metrics to pass to the optimizer.
197197
# Issue: https://github.com/microsoft/MLOS/issues/745
198-
self._opt.register(df_config, pd.DataFrame([registered_score], dtype=float))
198+
self._opt.register(configs=df_config, scores=pd.DataFrame([registered_score], dtype=float))
199199
return registered_score
200200

201201
def get_best_observation(self) -> Union[Tuple[Dict[str, float], TunableGroups], Tuple[None, None]]:

mlos_bench/mlos_bench/tests/optimizers/toy_optimization_loop_test.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ def _optimize(env: Environment, opt: Optimizer) -> Tuple[float, TunableGroups]:
5050
config_df = config_to_dataframe(config)
5151
logger("config: %s", str(config))
5252
try:
53-
logger("prediction: %s", opt._opt.surrogate_predict(config_df))
53+
logger("prediction: %s", opt._opt.surrogate_predict(configs=config_df))
5454
except RuntimeError:
5555
pass
5656

mlos_core/mlos_core/optimizers/bayesian_optimizers/bayesian_optimizer.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -20,29 +20,29 @@ class BaseBayesianOptimizer(BaseOptimizer, metaclass=ABCMeta):
2020
"""Abstract base class defining the interface for Bayesian optimization."""
2121

2222
@abstractmethod
23-
def surrogate_predict(self, configurations: pd.DataFrame,
23+
def surrogate_predict(self, *, configs: pd.DataFrame,
2424
context: Optional[pd.DataFrame] = None) -> npt.NDArray:
2525
"""Obtain a prediction from this Bayesian optimizer's surrogate model for the given configuration(s).
2626
2727
Parameters
2828
----------
29-
configurations : pd.DataFrame
30-
Dataframe of configurations / parameters. The columns are parameter names and the rows are the configurations.
29+
configs : pd.DataFrame
30+
Dataframe of configs / parameters. The columns are parameter names and the rows are the configs.
3131
3232
context : pd.DataFrame
3333
Not Yet Implemented.
3434
"""
3535
pass # pylint: disable=unnecessary-pass # pragma: no cover
3636

3737
@abstractmethod
38-
def acquisition_function(self, configurations: pd.DataFrame,
38+
def acquisition_function(self, *, configs: pd.DataFrame,
3939
context: Optional[pd.DataFrame] = None) -> npt.NDArray:
4040
"""Invokes the acquisition function from this Bayesian optimizer for the given configuration.
4141
4242
Parameters
4343
----------
44-
configurations : pd.DataFrame
45-
Dataframe of configurations / parameters. The columns are parameter names and the rows are the configurations.
44+
configs : pd.DataFrame
45+
Dataframe of configs / parameters. The columns are parameter names and the rows are the configs.
4646
4747
context : pd.DataFrame
4848
Not Yet Implemented.

mlos_core/mlos_core/optimizers/bayesian_optimizers/smac_optimizer.py

+24-24
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,10 @@ def __init__(self, *, # pylint: disable=too-many-locals,too-many-arguments
8080
See Also: mlos_bench.optimizer.bulk_register
8181
8282
max_ratio : Optional[int]
83-
Maximum ratio of max_trials to be random configurations to be evaluated
83+
Maximum ratio of max_trials to be random configs to be evaluated
8484
at start to bootstrap the optimizer.
8585
Useful if you want to explicitly control the number of random
86-
configurations evaluated at start.
86+
configs evaluated at start.
8787
8888
use_default_config: bool
8989
Whether to use the default config for the first trial after random initialization.
@@ -168,7 +168,7 @@ def __init__(self, *, # pylint: disable=too-many-locals,too-many-arguments
168168
initial_design_args['n_configs'] = n_random_init
169169
if n_random_init > 0.25 * max_trials and max_ratio is None:
170170
warning(
171-
'Number of random initial configurations (%d) is ' +
171+
'Number of random initial configs (%d) is ' +
172172
'greater than 25%% of max_trials (%d). ' +
173173
'Consider setting max_ratio to avoid SMAC overriding n_random_init.',
174174
n_random_init,
@@ -241,17 +241,17 @@ def _dummy_target_func(config: ConfigSpace.Configuration, seed: int = 0) -> None
241241
# -- this planned to be fixed in some future release: https://github.com/automl/SMAC3/issues/946
242242
raise RuntimeError('This function should never be called.')
243243

244-
def _register(self, configurations: pd.DataFrame,
244+
def _register(self, *, configs: pd.DataFrame,
245245
scores: pd.DataFrame, context: Optional[pd.DataFrame] = None) -> None:
246-
"""Registers the given configurations and scores.
246+
"""Registers the given configs and scores.
247247
248248
Parameters
249249
----------
250-
configurations : pd.DataFrame
251-
Dataframe of configurations / parameters. The columns are parameter names and the rows are the configurations.
250+
configs : pd.DataFrame
251+
Dataframe of configs / parameters. The columns are parameter names and the rows are the configs.
252252
253253
scores : pd.DataFrame
254-
Scores from running the configurations. The index is the same as the index of the configurations.
254+
Scores from running the configs. The index is the same as the index of the configs.
255255
256256
context : pd.DataFrame
257257
Not Yet Implemented.
@@ -262,7 +262,7 @@ def _register(self, configurations: pd.DataFrame,
262262
warn(f"Not Implemented: Ignoring context {list(context.columns)}", UserWarning)
263263

264264
# Register each trial (one-by-one)
265-
for (config, (_i, score)) in zip(self._to_configspace_configs(configurations), scores.iterrows()):
265+
for (config, (_i, score)) in zip(self._to_configspace_configs(configs=configs), scores.iterrows()):
266266
# Retrieve previously generated TrialInfo (returned by .ask()) or create new TrialInfo instance
267267
info: TrialInfo = self.trial_info_map.get(
268268
config, TrialInfo(config=config, seed=self.base_optimizer.scenario.seed))
@@ -272,7 +272,7 @@ def _register(self, configurations: pd.DataFrame,
272272
# Save optimizer once we register all configs
273273
self.base_optimizer.optimizer.save()
274274

275-
def _suggest(self, context: Optional[pd.DataFrame] = None) -> pd.DataFrame:
275+
def _suggest(self, *, context: Optional[pd.DataFrame] = None) -> pd.DataFrame:
276276
"""Suggests a new configuration.
277277
278278
Parameters
@@ -299,10 +299,10 @@ def _suggest(self, context: Optional[pd.DataFrame] = None) -> pd.DataFrame:
299299
config_df = pd.DataFrame([trial.config], columns=list(self.optimizer_parameter_space.keys()))
300300
return config_df
301301

302-
def register_pending(self, configurations: pd.DataFrame, context: Optional[pd.DataFrame] = None) -> None:
302+
def register_pending(self, *, configs: pd.DataFrame, context: Optional[pd.DataFrame] = None) -> None:
303303
raise NotImplementedError()
304304

305-
def surrogate_predict(self, configurations: pd.DataFrame, context: Optional[pd.DataFrame] = None) -> npt.NDArray:
305+
def surrogate_predict(self, *, configs: pd.DataFrame, context: Optional[pd.DataFrame] = None) -> npt.NDArray:
306306
from smac.utils.configspace import convert_configurations_to_array # pylint: disable=import-outside-toplevel
307307

308308
if context is not None:
@@ -318,11 +318,11 @@ def surrogate_predict(self, configurations: pd.DataFrame, context: Optional[pd.D
318318
if self.base_optimizer._config_selector._model is None:
319319
raise RuntimeError('Surrogate model is not yet trained')
320320

321-
configs: npt.NDArray = convert_configurations_to_array(self._to_configspace_configs(configurations))
322-
mean_predictions, _ = self.base_optimizer._config_selector._model.predict(configs)
321+
config_array: npt.NDArray = convert_configurations_to_array(self._to_configspace_configs(configs=configs))
322+
mean_predictions, _ = self.base_optimizer._config_selector._model.predict(config_array)
323323
return mean_predictions.reshape(-1,)
324324

325-
def acquisition_function(self, configurations: pd.DataFrame, context: Optional[pd.DataFrame] = None) -> npt.NDArray:
325+
def acquisition_function(self, *, configs: pd.DataFrame, context: Optional[pd.DataFrame] = None) -> npt.NDArray:
326326
if context is not None:
327327
warn(f"Not Implemented: Ignoring context {list(context.columns)}", UserWarning)
328328
if self._space_adapter:
@@ -332,28 +332,28 @@ def acquisition_function(self, configurations: pd.DataFrame, context: Optional[p
332332
if self.base_optimizer._config_selector._acquisition_function is None:
333333
raise RuntimeError('Acquisition function is not yet initialized')
334334

335-
configs: list = self._to_configspace_configs(configurations)
336-
return self.base_optimizer._config_selector._acquisition_function(configs).reshape(-1,)
335+
cs_configs: list = self._to_configspace_configs(configs=configs)
336+
return self.base_optimizer._config_selector._acquisition_function(cs_configs).reshape(-1,)
337337

338338
def cleanup(self) -> None:
339339
if self._temp_output_directory is not None:
340340
self._temp_output_directory.cleanup()
341341
self._temp_output_directory = None
342342

343-
def _to_configspace_configs(self, configurations: pd.DataFrame) -> List[ConfigSpace.Configuration]:
344-
"""Convert a dataframe of configurations to a list of ConfigSpace configurations.
343+
def _to_configspace_configs(self, *, configs: pd.DataFrame) -> List[ConfigSpace.Configuration]:
344+
"""Convert a dataframe of configs to a list of ConfigSpace configs.
345345
346346
Parameters
347347
----------
348-
configurations : pd.DataFrame
349-
Dataframe of configurations / parameters. The columns are parameter names and the rows are the configurations.
348+
configs : pd.DataFrame
349+
Dataframe of configs / parameters. The columns are parameter names and the rows are the configs.
350350
351351
Returns
352352
-------
353-
configurations : list
354-
List of ConfigSpace configurations.
353+
configs : list
354+
List of ConfigSpace configs.
355355
"""
356356
return [
357357
ConfigSpace.Configuration(self.optimizer_parameter_space, values=config.to_dict())
358-
for (_, config) in configurations.astype('O').iterrows()
358+
for (_, config) in configs.astype('O').iterrows()
359359
]

mlos_core/mlos_core/optimizers/flaml_optimizer.py

+9-9
Original file line numberDiff line numberDiff line change
@@ -85,24 +85,24 @@ def __init__(self, *, # pylint: disable=too-many-arguments
8585
self.evaluated_samples: Dict[ConfigSpace.Configuration, EvaluatedSample] = {}
8686
self._suggested_config: Optional[dict]
8787

88-
def _register(self, configurations: pd.DataFrame, scores: pd.DataFrame,
88+
def _register(self, *, configs: pd.DataFrame, scores: pd.DataFrame,
8989
context: Optional[pd.DataFrame] = None) -> None:
90-
"""Registers the given configurations and scores.
90+
"""Registers the given configs and scores.
9191
9292
Parameters
9393
----------
94-
configurations : pd.DataFrame
95-
Dataframe of configurations / parameters. The columns are parameter names and the rows are the configurations.
94+
configs : pd.DataFrame
95+
Dataframe of configs / parameters. The columns are parameter names and the rows are the configs.
9696
9797
scores : pd.DataFrame
98-
Scores from running the configurations. The index is the same as the index of the configurations.
98+
Scores from running the configs. The index is the same as the index of the configs.
9999
100100
context : None
101101
Not Yet Implemented.
102102
"""
103103
if context is not None:
104104
warn(f"Not Implemented: Ignoring context {list(context.columns)}", UserWarning)
105-
for (_, config), (_, score) in zip(configurations.astype('O').iterrows(), scores.iterrows()):
105+
for (_, config), (_, score) in zip(configs.astype('O').iterrows(), scores.iterrows()):
106106
cs_config: ConfigSpace.Configuration = ConfigSpace.Configuration(
107107
self.optimizer_parameter_space, values=config.to_dict())
108108
if cs_config in self.evaluated_samples:
@@ -112,7 +112,7 @@ def _register(self, configurations: pd.DataFrame, scores: pd.DataFrame,
112112
score=float(np.average(score.astype(float), weights=self._objective_weights)),
113113
)
114114

115-
def _suggest(self, context: Optional[pd.DataFrame] = None) -> pd.DataFrame:
115+
def _suggest(self, *, context: Optional[pd.DataFrame] = None) -> pd.DataFrame:
116116
"""Suggests a new configuration.
117117
118118
Sampled at random using ConfigSpace.
@@ -132,7 +132,7 @@ def _suggest(self, context: Optional[pd.DataFrame] = None) -> pd.DataFrame:
132132
config: dict = self._get_next_config()
133133
return pd.DataFrame(config, index=[0])
134134

135-
def register_pending(self, configurations: pd.DataFrame,
135+
def register_pending(self, *, configs: pd.DataFrame,
136136
context: Optional[pd.DataFrame] = None) -> None:
137137
raise NotImplementedError()
138138

@@ -165,7 +165,7 @@ def _get_next_config(self) -> dict:
165165
166166
Since FLAML does not provide an ask-and-tell interface, we need to create a new instance of FLAML
167167
each time we get asked for a new suggestion. This is suboptimal performance-wise, but works.
168-
To do so, we use any previously evaluated configurations to bootstrap FLAML (i.e., warm-start).
168+
To do so, we use any previously evaluated configs to bootstrap FLAML (i.e., warm-start).
169169
For more info: https://microsoft.github.io/FLAML/docs/Use-Cases/Tune-User-Defined-Function#warm-start
170170
171171
Returns

0 commit comments

Comments
 (0)