def predict_next_configurations(self, amount): """ Takes features, using previously created model makes regression to find labels and return label with the lowest value. :param amount: int number of Configurations which will be returned :return: list of Configurations that are needed to be measured. """ # 1. get model's predictions predicted_results = [] for index, predicted_result in sorted(enumerate( self.model.predict(self.experiment.search_space)), key=lambda c: c[1]): conf = self.experiment.search_space[index] predicted_results.append((predicted_result, conf)) # Only for DEMO # self.sub.send('predictions', 'configurations', # configurations=[self.experiment.search_space[index] for (predicted_result, index) in predicted_results], # results=[[round(predicted_result[0], 2)] for (predicted_result, index) in predicted_results]) # 2. Update predicted results for already evaluated Configurations. for config in self.all_configurations: for pred_tuple in predicted_results: if (pred_tuple[1] == config.get_parameters()): config.add_predicted_result(pred_tuple[1], pred_tuple[0]) # 3. Pick up requared amount of configs all_config = [ conf.get_parameters() for conf in self.all_configurations ] result = [] for best in predicted_results[:amount]: if best[1] in all_config: select = [ conf for conf in self.all_configurations if conf.get_parameters() == best[1] ] result.append(select[0]) else: new_conf = Configuration(best[1]) new_conf.add_predicted_result(best[1], best[0]) result.append(new_conf) # 4. return configs return result
def __predict_next_configuration(self): """ Predicts the solution candidate of the model. Returns old Configuration instance if configuration is already exists in all_configuration list, otherwise creates new Configuration instance. :return Configuration instance """ predicted_configuration = None info_dict = {} if self.isMinimizationExperiment: predicted_result = np.inf else: predicted_result = -np.inf predicted_result_vector = None if predicted_configuration is None: try: l = self.model['good'].pdf g = self.model['bad'].pdf minimize_me = lambda x: max(1e-32, g(x)) / max(l(x), 1e-32) kde_good = self.model['good'] kde_bad = self.model['bad'] for i in range(self.num_samples): idx = np.random.randint(0, len(kde_good.data)) datum = kde_good.data[idx] vector = [] for m, bw, t in zip(datum, kde_good.bw, self.vartypes): bw = max(bw, self.min_bandwidth) if t == 0: bw = self.bw_factor * bw try: vector.append( sps.truncnorm.rvs(-m / bw, (1 - m) / bw, loc=m, scale=bw)) except: self.logger.warning( "Truncated Normal failed for:\ndatum=%s\nbandwidth=%s\nfor entry with value %s" % (datum, kde_good.bw, m)) self.logger.warning("data in the KDE:\n%s" % kde_good.data) else: if np.random.rand() < (1 - bw): vector.append(int(m)) else: vector.append(np.random.randint(t)) val = minimize_me(vector) if not np.isfinite(val): # right now, this happens because a KDE does not contain all values for a categorical parameter # this cannot be fixed with the statsmodels KDE, so for now, we are just going to evaluate this one # if the good_kde has a finite value, i.e. there is no config with that value in the bad kde, so it shouldn't be terrible. if np.isfinite(l(vector)): predicted_result_vector = vector break if (val < predicted_result and self.isMinimizationExperiment) or ( val > predicted_result and not self.isMinimizationExperiment): predicted_result = val predicted_result_vector = vector if predicted_result_vector is None: self.logger.info( "Sampling based optimization with %i samples failed -> using random configuration" % self.num_samples) info_dict['model_based_pick'] = False else: predicted_configuration = [] for index, dimension in enumerate( self.experiment.description["DomainDescription"] ["AllConfigurations"]): predicted_configuration.append( dimension[predicted_result_vector[index]]) except: self.logger.warning( "Sampling based optimization with %i samples failed\n %s\n" "Using random configuration" % (self.num_samples, traceback.format_exc())) info_dict['model_based_pick'] = False # self.logger.debug('done sampling a new configuration.') for configuration in self.all_configurations: if configuration.get_parameters() == predicted_configuration: configuration.add_predicted_result( parameters=predicted_configuration, predicted_result=[predicted_result]) return configuration predicted_configuration_class = Configuration(predicted_configuration) predicted_configuration_class.add_predicted_result( parameters=predicted_configuration, predicted_result=[predicted_result]) return predicted_configuration_class