77 lines
2.6 KiB
Python
77 lines
2.6 KiB
Python
"""Bayesian optimization."""
|
|
|
|
from typing import Dict, Any, Callable
|
|
from src.core.logger import get_logger
|
|
|
|
logger = get_logger(__name__)
|
|
|
|
|
|
class BayesianOptimizer:
|
|
"""Bayesian optimization using scikit-optimize."""
|
|
|
|
def __init__(self):
|
|
"""Initialize Bayesian optimizer."""
|
|
self.logger = get_logger(__name__)
|
|
|
|
def optimize(
|
|
self,
|
|
param_space: Dict[str, Any],
|
|
objective_function: Callable[[Dict[str, Any]], float],
|
|
n_calls: int = 50,
|
|
maximize: bool = True
|
|
) -> Dict[str, Any]:
|
|
"""Run Bayesian optimization.
|
|
|
|
Args:
|
|
param_space: Parameter space definition
|
|
objective_function: Objective function
|
|
n_calls: Number of optimization iterations
|
|
maximize: True to maximize, False to minimize
|
|
|
|
Returns:
|
|
Best parameters and score
|
|
"""
|
|
try:
|
|
from skopt import gp_minimize
|
|
from skopt.space import Real, Integer
|
|
|
|
# Convert param_space to skopt format
|
|
dimensions = []
|
|
param_names = []
|
|
for name, space in param_space.items():
|
|
param_names.append(name)
|
|
if isinstance(space, tuple):
|
|
if isinstance(space[0], int):
|
|
dimensions.append(Integer(space[0], space[1], name=name))
|
|
else:
|
|
dimensions.append(Real(space[0], space[1], name=name))
|
|
|
|
# Wrapper function
|
|
def objective(params):
|
|
param_dict = dict(zip(param_names, params))
|
|
score = objective_function(param_dict)
|
|
return -score if maximize else score
|
|
|
|
result = gp_minimize(
|
|
objective,
|
|
dimensions,
|
|
n_calls=n_calls,
|
|
random_state=42
|
|
)
|
|
|
|
best_params = dict(zip(param_names, result.x))
|
|
best_score = -result.fun if maximize else result.fun
|
|
|
|
return {
|
|
"best_params": best_params,
|
|
"best_score": best_score,
|
|
}
|
|
except ImportError:
|
|
logger.warning("scikit-optimize not available, using grid search fallback")
|
|
from .grid_search import GridSearchOptimizer
|
|
optimizer = GridSearchOptimizer()
|
|
# Convert param_space to grid format
|
|
param_grid = {k: [v[0], v[1], (v[0] + v[1]) / 2] for k, v in param_space.items()}
|
|
return optimizer.optimize(param_grid, objective_function, maximize)
|
|
|