Passed
Push — master ( 626f23...be3b1e )
by Simon
01:48
created

ExpectedImprovementBasedOptimization.iterate()   A

Complexity

Conditions 1

Size

Total Lines 4
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
# Author: Simon Blanke
2
# Email: [email protected]
3
# License: MIT License
4
5
6
import numpy as np
7
from scipy.stats import norm
8
9
from .smbo import SMBO
10
11
12
def normalize(array):
13
    num = array - array.min()
14
    den = array.max() - array.min()
15
16
    if den == 0:
17
        return np.random.random_sample(array.shape)
18
    else:
19
        return ((num / den) + 0) / 1
20
21
22
class ExpectedImprovementBasedOptimization(SMBO):
23
    def __init__(
24
        self,
25
        *args,
26
        xi=0.01,
27
        warm_start_smbo=None,
28
        sampling={"random": 1000000},
29
        warnings=100000000,
30
        **kwargs,
31
    ):
32
        super().__init__(*args, **kwargs)
33
        self.new_positions = []
34
        self.xi = xi
35
        self.warm_start_smbo = warm_start_smbo
36
        self.sampling = sampling
37
        self.warnings = warnings
38
39
    def _expected_improvement(self):
40
        all_pos_comb = self._all_possible_pos()
41
        self.pos_comb = self._sampling(all_pos_comb)
42
43
        mu, sigma = self.regr.predict(self.pos_comb, return_std=True)
44
        # mu_sample = self.regr.predict(self.X_sample)
45
        mu = mu.reshape(-1, 1)
46
        sigma = sigma.reshape(-1, 1)
47
48
        Y_sample = normalize(np.array(self.Y_sample)).reshape(-1, 1)
49
        imp = mu - np.max(Y_sample) - self.xi
50
        Z = np.divide(imp, sigma, out=np.zeros_like(sigma), where=sigma != 0)
51
52
        exploit = imp * norm.cdf(Z)
53
        explore = sigma * norm.pdf(Z)
54
55
        exp_imp = exploit + explore
56
        exp_imp[sigma == 0.0] = 0.0
57
58
        return exp_imp[:, 0]
59
60
    def _propose_location(self):
61
        X_sample = np.array(self.X_sample)
62
        Y_sample = np.array(self.Y_sample)
63
64
        if len(Y_sample) == 0:
65
            return self.move_random()
66
67
        Y_sample = normalize(Y_sample).reshape(-1, 1)
68
        self.regr.fit(X_sample, Y_sample)
69
70
        exp_imp = self._expected_improvement()
71
72
        index_best = list(exp_imp.argsort()[::-1])
73
        all_pos_comb_sorted = self.pos_comb[index_best]
74
        pos_best = all_pos_comb_sorted[0]
75
76
        return pos_best
77
78
    @SMBO.track_nth_iter
79
    @SMBO.track_X_sample
80
    def iterate(self):
81
        return self._propose_location()
82
83
    @SMBO.track_y_sample
84
    def evaluate(self, score_new):
85
        self.score_new = score_new
86
87
        self._evaluate_new2current(score_new)
88
        self._evaluate_current2best()
89