gradient_free_optimizers/optimizers/smb_opt/forest_optimizer.py
# Author: Simon Blanke
# Email: simon.blanke@yahoo.com
# License: MIT License
import numpy as np
from scipy.stats import norm
from .smbo import SMBO
from .surrogate_models import (
RandomForestRegressor,
ExtraTreesRegressor,
GradientBoostingRegressor,
)
from .acquisition_function import ExpectedImprovement
tree_regressor_dict = {
"random_forest": RandomForestRegressor,
"extra_tree": ExtraTreesRegressor,
"gradient_boost": GradientBoostingRegressor,
}
def normalize(array):
num = array - array.min()
den = array.max() - array.min()
if den == 0:
return np.random.random_sample(array.shape)
else:
return ((num / den) + 0) / 1
class ForestOptimizer(SMBO):
name = "Forest Optimization"
_name_ = "forest_optimization"
__name__ = "ForestOptimizer"
optimizer_type = "sequential"
computationally_expensive = True
"""Based on the forest-optimizer in the scikit-optimize package"""
def __init__(
self,
*args,
tree_regressor="extra_tree",
tree_para={"n_estimators": 100},
xi=0.03,
**kwargs
):
super().__init__(*args, **kwargs)
self.tree_regressor = tree_regressor
self.tree_para = tree_para
self.regr = tree_regressor_dict[tree_regressor](**self.tree_para)
self.xi = xi
def finish_initialization(self):
self.all_pos_comb = self._all_possible_pos()
return super().finish_initialization()
def _expected_improvement(self):
self.pos_comb = self._sampling(self.all_pos_comb)
acqu_func = ExpectedImprovement(self.regr, self.pos_comb, self.xi)
return acqu_func.calculate(self.X_sample, self.Y_sample)
def _training(self):
X_sample = np.array(self.X_sample)
Y_sample = np.array(self.Y_sample)
if len(Y_sample) == 0:
return self.move_random()
Y_sample = normalize(Y_sample).reshape(-1, 1)
self.regr.fit(X_sample, Y_sample)