Esempio n. 1
0
 def print_mutation_rate_and_strength(self):
     support.write_to_file(
         self.log_file, 'Current mean mutation rate: ' +
         support.float_representation(self.cur_mutation_rate, 5))
     n_params = self.models[0].get_number_of_params()
     support.write_to_file(
         self.log_file, 'Current mean number of params to change: ' +
         str(max(1, int(n_params * self.cur_mutation_strength))))
Esempio n. 2
0
 def increase_models_complexity():
     support.write_to_file(self.log_file,
                           "\nIncrease models' complexities:")
     self.models = copy.deepcopy(self.models)
     index = None
     for model in self.models:
         index = model.increase_complexity(index)
     self.without_changes = 0
     self.select(self.size_of_generation, print_iter=False)
     self.cur_mutation_rate = self.params.mutation_rate
     self.cur_mutation_strength = self.params.mutation_strength
Esempio n. 3
0
        def run_one_ga_and_one_ls():
            while (not self.is_stoped() and self.run_before_ls):
                self.run_one_iteration()
                if shared_dict is not None:
                    shared_dict[self.prefix] = (copy.deepcopy(self.models[0]),
                                                self.final_models)
            if not self.run_before_ls:
                self.run_before_ls = True
            if self.run_ls:
                best_model = copy.deepcopy(self.models[0])
                support.write_to_file(
                    self.log_file, '\nTry to improve best model (' +
                    self.params.optimize_name + ')')
                try:  # catch error of `Factor is exactly singular`
                    if self.params.optimize_name != 'hill_climbing':
                        if self.out_dir is not None:
                            self.models[0].run_local_search(
                                self.params.optimize_name,
                                os.path.join(
                                    self.out_dir, self.params.optimize_name +
                                    '_' + str(self.cur_iteration) + '_out'))
                        else:
                            self.models[0].run_local_search(
                                self.params.optimize_name, None)
                        self.check_best_aic()
                    else:
                        self.run_hill_climbing_of_best()
                    self.print_and_draw_best_model(suffix='_ls')
                except RuntimeError as e:
                    if e.message == 'Factor is exactly singular':
                        support.write_log(
                            self.log_file,
                            'Local search failed of the following error: Factor is exactly singular.'
                        )
                    self.models[0] = best_model

            if not self.run_ls:
                self.run_ls = True

            if shared_dict is not None:
                shared_dict[self.prefix] = (copy.deepcopy(self.models[0]),
                                            self.final_models)
            self.check_best_aic()
            self.check_claic()
            self.final_models.append(self.best_model())
            self.pickle_final_models()

            support.print_final_model(self.log_file, self.models[0],
                                      self.params)

            self.cur_iteration += 1
Esempio n. 4
0
    def select(self, size, print_iter=True):
        """Selection in population of models.

        size :   size of result population

        If size of current population is bigger than size, then we discard the worst.
        """
        self.models = sorted(
            self.models, key=lambda x: x.get_fitness_func_value())[:size]
        if print_iter:
            support.write_to_file(self.log_file,
                                  '\n\nIteration #' + str(self.cur_iteration) + '.')

        support.print_set_of_models(self.log_file, list(enumerate(self.models)), 
                self.params, first_col='N\t', heading='Current population of models:')
Esempio n. 5
0
    def run(self, shared_dict=None):
        """Main function to run genetic algorithm.

        shared_dict :   dictionary to share information among processes.
        """
        # checking dirs
        if self.prefix is not None:
            self.out_dir = os.path.join(self.params.output_dir, self.prefix)
            if not os.path.exists(self.out_dir):
                os.makedirs(self.out_dir)
            if not self.params.draw_iter == 0:
                support.ensure_dir_existence(
                    os.path.join(self.out_dir, 'pictures'))
            if not self.params.code_iter == 0:
                support.ensure_dir_existence(
                    os.path.join(self.out_dir, 'python_code'))
                support.ensure_dir_existence(os.path.join(
                    self.out_dir, 'python_code', 'dadi'))
                support.ensure_dir_existence(os.path.join(
                    self.out_dir, 'python_code', 'moments'))
            self.log_file = os.path.join(self.out_dir, 'GADMA_GA.log')
            open(self.log_file, 'a').close()
        else:
            self.log_file = None

        # help functions
        def run_one_ga_and_one_ls():
            while (not self.is_stoped() and self.run_before_ls):
                self.run_one_iteration()
                if shared_dict is not None:
                    shared_dict[self.prefix] = (
                        copy.deepcopy(self.models[0]), self.final_models)
            if not self.run_before_ls:
                self.run_before_ls = True
            if self.run_ls:
                best_model = copy.deepcopy(self.models[0])
                support.write_to_file(
                    self.log_file,
                    '\nTry to improve best model (' +
                    self.params.optimize_name +
                    ')')
                try: # catch error of `Factor is exactly singular`
                    if self.params.optimize_name != 'hill_climbing':
                        if self.out_dir is not None:
                            self.models[0].run_local_search(self.params.optimize_name, os.path.join(
                                self.out_dir, self.params.optimize_name + '_' + str(self.cur_iteration) + '_out'))
                        else:
                            self.models[0].run_local_search(self.params.optimize_name, None)
                        self.check_best_aic()
                    else:
                        self.run_hill_climbing_of_best()
                    self.print_and_draw_best_model(suffix='_ls')
                except RuntimeError as e:
                    if e.message == 'Factor is exactly singular':
                        support.write_log(self.log_file, 
                                'Local search failed of the following error: Factor is exactly singular.')
                    self.models[0] = best_model
                        
            if not self.run_ls:
                self.run_ls = True

            if shared_dict is not None:
                shared_dict[self.prefix] = (
                    copy.deepcopy(self.models[0]), self.final_models)
            self.check_best_aic()
            self.check_claic()
            self.final_models.append(self.best_model())
            self.pickle_final_models()

            support.print_final_model(self.log_file, self.models[0], self.params)

            self.cur_iteration += 1


        def increase_models_complexity():
            support.write_to_file(self.log_file,
                                  "\nIncrease models' complexities:")
            self.models = copy.deepcopy(self.models)
            index = None
            for model in self.models:
                index = model.increase_complexity(index)
            self.without_changes = 0
            self.select(self.size_of_generation, print_iter=False)
            self.cur_mutation_rate = self.params.mutation_rate
            self.cur_mutation_strength = self.params.mutation_strength

        # begin
        support.write_to_file(self.log_file,
                              '--Start genetic algorithm pipeline--')

        # initialization of first population
        self.init_first_population_of_models()        
        if shared_dict is not None:
            shared_dict[
                self.prefix] = (
                copy.deepcopy(
                    self.models[0]),
                self.final_models)
        self.print_and_draw_best_model()
 

        self.cur_iteration += 1

        # main part
        run_one_ga_and_one_ls()
        
        if not self.is_custom_model:
            while not (self.models[0].get_structure() ==
                       self.params.final_structure).all():
                increase_models_complexity()
                run_one_ga_and_one_ls()

        for model in self.models:
            model.info = 'f'
        self.check_best_aic()

        if shared_dict is not None:
            shared_dict[self.prefix] = (
                copy.deepcopy(self.models[0]), self.final_models)

        # final part
        if self.out_dir is not None:
            self.print_and_draw_best_model(final=True)

        return self.best_model()
Esempio n. 6
0
    def run_one_iteration(self):
        """Iteration step for genetic algorithm."""
        start = time.time()

        # take  self.number_of_old_models best models from previous population
        new_models = self.models[:self.number_of_old_models]

        # create probabilities to choose models for crossing and mutation
        p = []
        for m in self.models:
            p.append(m.get_fitness_func_value())
        p = np.array(p)
        p -= max(p) + 1
        p = -p
        p /= sum(p)

        # add mutated models to our new population
        for i in xrange(self.number_of_mutated_models):
            model = self.get_mutated_model(
                mutation_strength=self.cur_mutation_strength,
                mutation_rate=self.cur_mutation_rate,
                p=p)
            new_models.append(model)

        # add crossed models to our new population
        for i in xrange(self.number_of_crossed_models):
            first_model_index = np.random.choice(xrange(len(self.models)), p=p)
            first_model = self.models[first_model_index]

            p[first_model_index] = 0
            p /= sum(p)
            second_model = np.random.choice(self.models, p=p)

            new_models.append(first_model.cross_with_other(second_model))

        # add random models to our new population
        for i in xrange(self.number_of_random_models):
            new_models.append(
                self.get_random_model(
                    structure=self.models[0].get_structure()))

        # remember prev best value of fitness function
        prev_value_of_fit = self.models[0].get_fitness_func_value()

        # new population become current population
        self.models = new_models

        # sort population by fitness function
        self.select(self.params.size_of_generation)

        self.print_and_draw_best_model() 

        # try to make better mutated and crossed models, random are so by
        # definition
        if self.without_changes == self.it_without_changes_to_stop_ga / 2 or self.is_stoped():
            prev_value_of_fit = self.best_fitness_value()
            support.write_to_file(
                self.log_file,
                '\nTime to normalize models with optmal_sfs_scaling:')
            for model in new_models:
                if model.info != 'r':
                    model.normalize_by_Nref()
            self.select(self.size_of_generation, print_iter=False)

        # update our adaptive mutation_rate and print it to log file
        self.update_mutation_rate_and_strength(prev_value_of_fit)
        self.print_mutation_rate_and_strength()
        self.check_best_aic()


        # check if we get stuck
        if abs(
                prev_value_of_fit -
                self.best_fitness_value()) < self.params.epsilon:
            self.without_changes += 1
        else:
            self.without_changes = 0
        self.cur_iteration += 1

        # print results to log file
        support.print_best_logll_model_long(self.log_file, self.best_model(), self.params)

        stop = time.time()
        self.work_time += stop - start
        support.write_to_file(self.log_file, '\nMean time: ', self.mean_time())