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
Exemple #2
0
 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
Exemple #3
0
    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
Exemple #4
0
 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