Пример #1
0
    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
Пример #2
0
    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