gradient_free_optimizers.optimizers.smb_opt.tree_structured_parzen_estimators   A
last analyzed

Complexity

Total Complexity 5

Size/Duplication

Total Lines 102
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 5
eloc 73
dl 0
loc 102
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A TreeStructuredParzenEstimators._training() 0 5 1
A TreeStructuredParzenEstimators.finish_initialization() 0 3 1
A TreeStructuredParzenEstimators.__init__() 0 37 1
A TreeStructuredParzenEstimators._expected_improvement() 0 20 1
A TreeStructuredParzenEstimators._get_samples() 0 13 1
1
# Author: Simon Blanke
2
# Email: [email protected]
3
# License: MIT License
4
5
6
import numpy as np
7
8
from sklearn.neighbors import KernelDensity
9
from .smbo import SMBO
10
11
12
class TreeStructuredParzenEstimators(SMBO):
13
    name = "Tree Structured Parzen Estimators"
14
    _name_ = "tree_structured_parzen_estimators"
15
    __name__ = "TreeStructuredParzenEstimators"
16
17
    optimizer_type = "sequential"
18
    computationally_expensive = True
19
20
    def __init__(
21
        self,
22
        search_space,
23
        initialize={"grid": 4, "random": 2, "vertices": 4},
24
        constraints=[],
25
        random_state=None,
26
        rand_rest_p=0,
27
        nth_process=None,
28
        warm_start_smbo=None,
29
        max_sample_size=10000000,
30
        sampling={"random": 1000000},
31
        replacement=True,
32
        gamma_tpe=0.2,
33
    ):
34
        super().__init__(
35
            search_space=search_space,
36
            initialize=initialize,
37
            constraints=constraints,
38
            random_state=random_state,
39
            rand_rest_p=rand_rest_p,
40
            nth_process=nth_process,
41
            warm_start_smbo=warm_start_smbo,
42
            max_sample_size=max_sample_size,
43
            sampling=sampling,
44
            replacement=replacement,
45
        )
46
47
        self.gamma_tpe = gamma_tpe
48
49
        kde_para = {
50
            "kernel": "gaussian",
51
            "bandwidth": 1,
52
            "rtol": 0.001,
53
        }
54
55
        self.kd_best = KernelDensity(**kde_para)
56
        self.kd_worst = KernelDensity(**kde_para)
57
58
    def finish_initialization(self):
59
        self.all_pos_comb = self._all_possible_pos()
60
        return super().finish_initialization()
61
62
    def _get_samples(self):
63
        n_samples = len(self.X_sample)
64
        n_best = max(round(n_samples * self.gamma_tpe), 1)
65
66
        Y_sample = np.array(self.Y_sample)
67
        index_best = Y_sample.argsort()[-n_best:]
68
        n_worst = int(n_samples - n_best)
69
        index_worst = Y_sample.argsort()[:n_worst]
70
71
        best_samples = [self.X_sample[i] for i in index_best]
72
        worst_samples = [self.X_sample[i] for i in index_worst]
73
74
        return best_samples, worst_samples
75
76
    def _expected_improvement(self):
77
        self.pos_comb = self._sampling(self.all_pos_comb)
78
79
        logprob_best = self.kd_best.score_samples(self.pos_comb)
80
        logprob_worst = self.kd_worst.score_samples(self.pos_comb)
81
82
        prob_best = np.exp(logprob_best)
83
        prob_worst = np.exp(logprob_worst)
84
85
        WorstOverbest = np.divide(
86
            prob_worst,
87
            prob_best,
88
            out=np.zeros_like(prob_worst),
89
            where=prob_worst != 0,
90
        )
91
92
        exp_imp_inv = self.gamma_tpe + WorstOverbest * (1 - self.gamma_tpe)
93
        exp_imp = 1 / exp_imp_inv
94
95
        return exp_imp
96
97
    def _training(self):
98
        best_samples, worst_samples = self._get_samples()
99
100
        self.kd_best.fit(best_samples)
101
        self.kd_worst.fit(worst_samples)
102