Example #1
0
 def predict(
     self,
     X: np.ndarray = None,
     first_layer: np.ndarray = None,
     training: bool = False,
 ):
     if first_layer is None and self.model_trained is False:
         msg = "Model has not been trained yet"
         raise ModelError(msg)
     elif first_layer is not None:
         # Calculate the dot product + bias
         out = np.dot(X, first_layer[1:, :]) + first_layer[0]
         activated_layer = self.activate(out)
         last_layer = self.calculate_linear(activated_layer)
     elif first_layer is None:
         first_layer = self._first_layer
         last_layer = self._last_layer
         # Calculate the dot product + bias
         out = np.dot(X, first_layer[1:, :]) + first_layer[0]
         activated_layer = self.activate(out)
     else:
         msg = "How did you get here?"
         raise ModelError(msg)
     y_pred = np.dot(activated_layer, last_layer[1:, :]) + last_layer[0]
     if training:
         return y_pred
     else:
         return y_pred[:, 0], np.zeros_like(y_pred[:, 0])
Example #2
0
 def _model_performance(
     self,
     first_layer: np.ndarray = None,
     X: np.ndarray = None,
     y_true: np.ndarray = None,
 ):
     if first_layer is None and self.model_trained is False:
         msg = "Model has not been trained yet"
         raise ModelError(msg)
     if first_layer is None:
         first_layer = self._first_layer
     if X is None:
         X = self.X
         y = self.y
     if np.ndim(first_layer) == 3:
         loss = []
         complexity = []
         for actual_first_layer in first_layer:
             y_predict = self.predict(X=X,
                                      first_layer=actual_first_layer,
                                      training=True)
             loss.append(self.loss_function(y, y_predict))
             complexity.append(np.count_nonzero(actual_first_layer))
     elif np.ndim(first_layer) == 2:
         y_predict = self.predict(X=X,
                                  first_layer=first_layer,
                                  training=True)
         loss = self.loss_function(y, y_predict)
         complexity = np.count_nonzero(first_layer)
     return np.asarray((loss, complexity)).T
Example #3
0
 def _model_performance(
     self,
     individuals: np.ndarray = None,
     X: np.ndarray = None,
     y_true: np.ndarray = None,
 ):
     if individuals is None and self.model_trained is False:
         msg = "Model has not been trained yet"
         raise ModelError(msg)
     if individuals is None:
         individuals = self._subnets
     if X is None:
         X = self.X
         y = self.y
     if len(individuals) > 1:
         loss = []
         complexity = []
         for individual in individuals:
             penultimate_y_pred, ind_complexity = self._feed_forward(individual, X)
             y_pred, _ = self._calculate_linear(penultimate_y_pred)
             loss.append(self.loss_function(y, y_pred))
             complexity.append(ind_complexity)
     else:
         penultimate_y_pred, ind_complexity = self._feed_forward(individuals, X)
         y_pred, _ = self._calculate_linear(penultimate_y_pred)
         loss = self.loss_function(y, y_pred)
         complexity = ind_complexity
     return np.asarray((loss, complexity)).T
Example #4
0
    def fit(self, X: np.ndarray, y: np.ndarray):
        if isinstance(X, (pd.DataFrame, pd.Series)):
            X = X.values
        if isinstance(y, (pd.DataFrame, pd.Series)):
            y = y.values.reshape(-1, 1)
        if X.shape[0] != y.shape[0]:
            msg = (f"Ensure that the number of samples in X and y are the same"
                   f"Number of samples in X = {X.shape[0]}"
                   f"Number of samples in y = {y.shape[0]}")
            raise ModelError(msg)
        self.X = X
        self.y = y
        if self.subsets is None:
            self.subsets = []

            # Create random subsets of decision variables for each subnet

            for i in range(self.num_subnets):
                n = random.randint(1, self.X.shape[1])
                self.subsets.append(random.sample(range(self.X.shape[1]), n))

            # Ensure that each decision variable is used as an input in at least one subnet
            for n in list(range(self.X.shape[1])):
                if not any(n in k for k in self.subsets):
                    self.subsets[random.randint(0, self.num_subnets -
                                                1)].append(n)

        # Create problem
        problem = surrogateProblem(
            performance_evaluator=self._model_performance)
        problem.n_of_objectives = 2
        # Create Population
        initial_pop = self._create_individuals()
        population = SurrogatePopulation(problem, self.pop_size, initial_pop,
                                         None, None, None)
        # Do evolution
        evolver = self.training_algorithm(problem,
                                          initial_population=population)
        recombinator = EvoDN2Recombination(evolver=evolver)
        evolver.population.recombination = recombinator
        figure = animate_init_(evolver.population.objectives,
                               filename="EvoDN2.html")
        while evolver.continue_evolution():
            evolver.iterate()
            figure = animate_next_(
                evolver.population.objectives,
                figure,
                filename="EvoDN2.html",
                generation=evolver._iteration_counter,
            )
        self.model_population = evolver.population
        # Selection
        self.select()
        self.model_trained = True
Example #5
0
 def select(self):
     if self.model_selection_criterion == "min_error":
         # Return the model with the lowest error
         selected = np.argmin(self.model_population.objectives[:, 0])
     else:
         raise ModelError(
             "Selection criterion not recognized. Use 'min_error'.")
     self.tree = self.model_population.individuals[selected][0]
     y_pred = self.predict(X=self.X)
     self.performance["RMSE"] = np.sqrt(mean_squared_error(self.y, y_pred))
     self.performance["R^2"] = r2_score(self.y, y_pred)
Example #6
0
 def activate(self, x):
     if self.activation_function == "sigmoid":
         return expit(x)
     elif self.activation_function == "relu":
         return np.maximum(x, 0)
     elif self.activation_function == "tanh":
         return np.tanh(x)
     else:
         msg = (
             f"Given activation function not recognized: {self.activation_function}"
             f"\nActivation function should be one of ['relu', 'sigmoid', 'tanh']"
         )
         raise ModelError(msg)
Example #7
0
 def select(self):
     if self.model_selection_criterion == "min_error":
         # Return the model with the lowest error
         selected = np.argmin(self.model_population.objectives[:, 0])
     else:
         raise ModelError("Selection criterion not recognized. Use 'min_error'.")
     self.subnets = self.model_population.individuals[selected]
     penultimate_y_pred, complexity = self._feed_forward(self.subnets, self.X)
     y_pred, linear_layer = self._calculate_linear(penultimate_y_pred)
     self._last_layer = linear_layer
     self.performance["RMSE"] = np.sqrt(mean_squared_error(self.y, y_pred))
     self.performance["R^2"] = r2_score(self.y, y_pred)
     self.performance["Complexity"] = complexity
Example #8
0
 def self_distance(self, arr):
     if arr.ndim == 1:
         dist = np.abs(np.subtract(arr[None, :], arr[:, None]))
     elif arr.ndim == 2:
         dist = np.sum(np.abs(np.subtract(arr[None, :, :], arr[:,
                                                               None, :])),
                       axis=2)
     else:
         msg = (
             f"Array of wrong dimension. Expected dimension = 1 or 2. Recieved "
             f"dimension = {arr.ndim}")
         raise ModelError(msg)
     return dist
Example #9
0
    def fit(self, X: np.ndarray, y: np.ndarray):
        if isinstance(X, (pd.DataFrame, pd.Series)):
            X = X.values
        if isinstance(y, (pd.DataFrame, pd.Series)):
            y = y.values.reshape(-1, 1)
        if X.shape[0] != y.shape[0]:
            msg = (f"Ensure that the number of samples in X and y are the same"
                   f"Number of samples in X = {X.shape[0]}"
                   f"Number of samples in y = {y.shape[0]}")
            raise ModelError(msg)
        self.X = X
        self.y = y

        # Create problem
        problem = surrogateProblem(
            performance_evaluator=self._model_performance)
        problem.n_of_objectives = 2
        # Create Population
        initial_pop = self._create_individuals()
        population = SurrogatePopulation(problem, self.pop_size, initial_pop,
                                         None, None, None)
        # Do evolution
        evolver = self.training_algorithm(problem,
                                          initial_population=population)
        recombinator = EvoNNRecombination(evolver=evolver,
                                          mutation_type=self.mutation_type)
        evolver.population.recombination = recombinator
        figure = animate_init_(evolver.population.objectives,
                               filename="EvoNN.html")
        while evolver.continue_evolution():
            evolver.iterate()
            figure = animate_next_(
                evolver.population.objectives,
                figure,
                filename="EvoNN.html",
                generation=evolver._iteration_counter,
            )
        self.model_population = evolver.population
        # Selection
        self.select()
        self.model_trained = True
Example #10
0
 def _model_performance(self,
                        trees: LinearNode,
                        X: np.ndarray = None,
                        y: np.ndarray = None):
     if trees is None and self.model_trained is False:
         msg = "Model has not been trained yet"
         raise ModelError(msg)
     if trees is None:
         trees = self.tree
     if X is None:
         X = self.X
         y = self.y
     if len(trees) > 1:
         loss = []
         complexity = []
         for tree in trees:
             y_pred, ind_complexity = tree[0].calculate_linear(X, y)
             loss.append(self.loss_function(y, y_pred))
             complexity.append(ind_complexity)
     else:
         y_pred, complexity = trees[0].calculate_linear(X, y)
         loss = self.loss_function(y, y_pred)
     return np.asarray((loss, complexity)).T
Example #11
0
    def fit(self, X: pd.DataFrame, y: pd.DataFrame):
        if X.shape[0] != y.shape[0]:
            msg = (f"Ensure that the number of samples in X and y are the same"
                   f"Number of samples in X = {X.shape[0]}"
                   f"Number of samples in y = {y.shape[0]}")
            raise ModelError(msg)
        self.X = X
        self.y = y
        if self.terminal_set is None:
            self.terminal_set = X.columns.tolist()

        # Create problem
        problem = surrogateProblem(
            performance_evaluator=self._model_performance)
        problem.n_of_objectives = 2
        # Create Population
        initial_pop = self._create_individuals()
        population = SurrogatePopulation(problem, self.pop_size, initial_pop,
                                         None, None, None)
        population.xover = BioGP_xover(
            probability_crossover=self.probability_crossover)
        population.mutation = BioGP_mutation(
            probability_mutation=self.probability_mutation)
        # Do single objective evolution
        tournament_evolver = TournamentEA(
            problem,
            initial_population=population,
            population_size=self.pop_size,
            n_gen_per_iter=self.single_obj_generations,
            n_iterations=1,
        )
        figure = animate_init_(tournament_evolver.population.objectives,
                               filename="BioGP.html")
        while tournament_evolver.continue_evolution():
            tournament_evolver.iterate()
            figure = animate_next_(
                tournament_evolver.population.objectives,
                figure,
                filename="BioGP.html",
                generation=tournament_evolver._iteration_counter,
            )
        population = tournament_evolver.population

        # Do bi-objective evolution
        evolver = self.training_algorithm(
            problem,
            initial_population=population,
            population_size=self.pop_size,
            n_gen_per_iter=10,
            n_iterations=10,
        )
        while evolver.continue_evolution():
            evolver.iterate()
            figure = animate_next_(
                evolver.population.objectives,
                figure,
                filename="BioGP.html",
                generation=evolver._iteration_counter +
                tournament_evolver._iteration_counter,
            )
        self.model_population = evolver.population
        # Selection
        self.select()
        self.model_trained = True