def transform(self, instance: Instance): """ for the binary case, the f_attack value represents the percentage of features we change. If f_attack =1, then the result should be exactly the same as innocuous target. for the real_value case, we generate a value between c_f(x_min - xij) and c_f(x_max - xij) This value will be added to the xij for the new instance :param instance: :return: instance """ if self.binary: attack_times = int(self.f_attack * self.num_features) count = 0 for i in range(0, self.num_features): instance.get_feature_vector().flip_bit(i) count += 1 if count == attack_times: return instance else: for i in range(0, self.num_features): xij = instance.get_feature_vector().get_feature(i) if not self.manual: lower_bound = self.f_attack * (self.x_min[i] - xij) upper_bound = self.f_attack * (self.x_max[i] - xij) else: lower_bound = self.f_attack * (self.xj_min - xij) upper_bound = self.f_attack * (self.xj_max - xij) delta_ij = random.uniform(lower_bound, upper_bound) instance.flip(i, xij + delta_ij) return instance
def transform(self, instance: Instance): ''' for the real_value case, we generate a value between 0 and the bound. The bound is calculated by 1- c_delta * (abs(xt - x)/abs(x) + abs(xt)) * (xt -x) This value will be added to the xij for the new instance :param instance: :return: instance ''' if self.binary: attack_times = int(self.f_attack * self.num_features) count = 0 for i in range(0, self.num_features): delta_ij = self.innocuous_target.get_feature_vector().get_feature(i) \ - instance.get_feature_vector().get_feature(i) if delta_ij != 0: if self.binary: # when features are binary instance.get_feature_vector().flip_bit(i) count += 1 if count == attack_times: return instance else: for i in range(0, self.num_features): xij = instance.get_feature_vector().get_feature(i) target = self.innocuous_target.get_feature_vector( ).get_feature(i) if abs(xij) + abs(target) == 0: bound = 0 else: bound = self.discount_factor * (1 - self.f_attack * (abs(target - xij) / (abs(xij) + abs(target)))) \ * abs((target - xij)) delta_ij = random.uniform(0, bound) instance.flip(i, xij + delta_ij) return instance
def transform(self, instance: Instance): ''' for the binary case, the f_attack value represents the percentage of features we change. If f_attack =1, then the result should be exactly the same as innocuous target. for the real_value case, we generate a value between c_f(x_min - xij) and c_f(x_max - xij) This value will be added to the xij for the new instance :param instance: :return: instance ''' if self.binary: attack_times = (int)(self.f_attack * self.num_features) count = 0 for i in range(0, self.num_features): delta_ij = (self.innocuous_target.get_feature_vector().get_feature(i) - instance.get_feature_vector().get_feature(i)) if delta_ij != 0: if self.binary: # when features are binary instance.get_feature_vector().flip_bit(i) count += 1 if count == attack_times: return instance else: for i in range(0, self.num_features): xij = instance.get_feature_vector().get_feature(i) if self.xj_min == 0 and self.xj_max == 0: lower_bound = self.f_attack * ( self.x_min.get_feature(i) - xij) upper_bound = self.f_attack * ( self.x_max.get_feature(i) - xij) else: lower_bound = self.f_attack * (self.xj_min - xij) upper_bound = self.f_attack * (self.xj_max - xij) # is that ok to just assign a random number between the range??? delta_ij = random.uniform(lower_bound, upper_bound) instance.flip(i, xij + delta_ij) return instance
def transform(self, instance: Instance): ''' for the real_value case, we generate a value between 0 and the bound. The bound is calculated by 1- c_delta * (abs(xt - x)/abs(x) + abs(xt)) * (xt -x) This value will be added to the xij for the new instance :param instance: :return: instance ''' for i in range(0, self.num_features): xij = instance.get_feature_vector().get_feature(i) target = self.innocuous_target.get_feature_vector().get_feature(i) if abs(xij) + abs(target) == 0: bound = 0 else: bound = self.discount_factor * (1 - self.f_attack * (abs(target - xij) / (abs(xij) + abs(target)))) \ * abs((target - xij)) # is that ok to just assign a random number between the range??? delta_ij = random.uniform(0, bound) instance.flip(i, xij + delta_ij) return instance