def get_next_point_EI(self, gaussian_process, exclude): # get the expected improvement of the whole input domain (in batches, might be slow otherwise) expected_improvement = np.zeros(self.input_domain.shape[0]) batch_size = 64 for curr_idx in range(0, self.input_domain.shape[0] + batch_size, batch_size): expected_improvement[curr_idx:curr_idx + batch_size] = get_expected_improvement( self.input_domain[curr_idx:curr_idx + batch_size], gaussian_process, self.history) # find the point with the highest EI, and which can be queried next next_point = self.input_domain[np.argmax(expected_improvement)] next_point_idx = 1 while array_in_matrix(next_point, exclude): if next_point_idx >= self.input_domain.shape[0]: "Run out of points to display next. You should end the experiment." break next_point = self.input_domain[np.argsort(-expected_improvement) [next_point_idx]] next_point_idx += 1 return next_point
def add_single_comparison(self, winner, loser): """ Add a single comparison to the dataset. :param winner: datapoint that wins the comparison :param loser: datapoint that loses the comparison :return: """ # only add the comparison if we don't compare the same datapoint if np.array_equal(winner, loser): print( "Watch out - trying to add comparison between same datapoints!" ) return False # add winner and loser to our datapoints and get the indices in dataset winner_idx = self._add_single_datapoint(winner) loser_idx = self._add_single_datapoint(loser) # add comparison if not utl_data.array_in_matrix([winner_idx, loser_idx], self.comparisons): self.comparisons = np.vstack( (self.comparisons, [winner_idx, loser_idx])) return True
def remove_inconsistencies(self): """ If there are inconsistencies in the comparisons, remove them. :return: """ comparisons_flipped = self.comparisons[:, [1, 0]] duplicate = utl_data.array_in_matrix(comparisons_flipped, self.comparisons) self.comparisons = self.comparisons[duplicate == 0, :]
def get_index(self, datapoint): """ Gets the index of a datapoint in the dataset, returns None if that doesn't exist :param datapoint: single datapoint :return: None if datapoint is not in the dataset, else the index of datapoint in the dataset """ if not utl_data.array_in_matrix(datapoint, self.datapoints): return None else: return np.argmax(np.sum(datapoint != self.datapoints, axis=1) == 0)
def get_next_point_thompson(self, gaussian_process, exclude): # get a sample sample_mean = gaussian_process.sample(self.input_domain) next_point = self.input_domain[np.argmax(sample_mean)] next_point_idx = 1 while array_in_matrix(next_point, exclude): if next_point_idx >= self.input_domain.shape[0]: "Run out of points to display next. You should end the experiment." break next_point = self.input_domain[np.argsort(-sample_mean) [next_point_idx]] next_point_idx += 1 return next_point
def _add_single_datapoint(self, new_datapoint): """ Add single datapoint to the existing dataset if it doesn't exist yet and return index :param new_datapoint: new datapoint to add :return x_new_idx: the index of the new datapoint in the existing dataset """ new_datapoint = utl_data.format_data(new_datapoint, self.num_objectives) # if the datapoint is not in our dataset yet, add it if not utl_data.array_in_matrix(new_datapoint, self.datapoints): self.datapoints = np.vstack((self.datapoints, new_datapoint)) new_datapoint_index = self.datapoints.shape[0] - 1 # if the datapoint is already in our dataset, find its index else: new_datapoint_index = self.get_index(new_datapoint) return new_datapoint_index