Source code for robustx.generators.CE_methods.GuidedBinaryLinearSearch

from robustx.lib.distance_functions.DistanceFunctions import euclidean
from robustx.generators.CEGenerator import CEGenerator
from robustx.robustness_evaluations.DeltaRobustnessEvaluator import DeltaRobustnessEvaluator


[docs] class GuidedBinaryLinearSearch(CEGenerator): def _generation_method(self, instance, gamma=0.1, column_name="target", neg_value=0, distance_func=euclidean, **kwargs): # Get initial counterfactual c = self.task.get_random_positive_instance(neg_value, column_name).T opt = DeltaRobustnessEvaluator(self.task) # Keep getting random positive counterfactual until we find one that is robust while not opt.evaluate(instance, desired_output=1 - neg_value): c = self.task.get_random_positive_instance(neg_value, column_name).T # Make sure column names are same so return result has same indices negative = instance.to_frame() c.columns = negative.columns model = self.task.model # Loop until CE is under gamma threshold while distance_func(negative, c) > gamma: # Calculate new CE by finding midpoint new_neg = c.add(negative, axis=0) / 2 # Reassign endpoints based on model prediction if model.predict_single(new_neg.T) == model.predict_single(negative.T): negative = new_neg else: c = new_neg # Form the dataframe ct = c.T # Store model prediction in return CE (this should ALWAYS be the positive value) res = model.predict_single(ct) ct["target"] = res # Store the loss ct["loss"] = distance_func(negative, c) return ct