Skip to content

Commit

Permalink
...
Browse files Browse the repository at this point in the history
  • Loading branch information
szczepanskiNicolas committed Feb 20, 2024
1 parent 18ccc5c commit 409cd29
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 20 deletions.
6 changes: 2 additions & 4 deletions pyxai/examples/DT/builder-rectify3.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@
"binary": ["PP", "R"],
}

print("bob = (25, 1, 1):")
bob = (25, 1, 1)
explainer = Explainer.initialize(tree, instance=bob, features_type=loan_types)
explainer = Explainer.initialize(tree, instance=(25, 1, 1), features_type=loan_types)

print("binary representation: ", explainer.binary_representation)
print("target_prediction:", explainer.target_prediction)
Expand All @@ -29,6 +27,6 @@
#For him/her, the following classification rule must be obeyed:
#whenever the annual income of the client is lower than 30,
#the demand should be rejected
rectified_model = explainer.rectify(decision_rule=(-1, ), label=0)
rectified_model = explainer.rectify(conditions=(-1, ), label=0)

assert (0, (1, 0, (4, (3, 0, 1), 1))) == rectified_model.raw_data_for_CPP(), "The rectified model is not good."
8 changes: 4 additions & 4 deletions pyxai/sources/core/explainer/explainerDT.py
Original file line number Diff line number Diff line change
Expand Up @@ -316,10 +316,10 @@ def simplify_theory(self, tree_rectified):
return tree_rectified
return tree_rectified

def rectify(self, *, decision_rule, label):
def rectify(self, *, conditions, label):
"""
Rectify the Decision Tree (self._tree) of the explainer according to a `decision_rule` and a `label`.
Simplify the final tree (the theory can help to eliminate some nodes).
Rectify the Decision Tree (self._tree) of the explainer according to a `conditions` and a `label`.
Simplify the model (the theory can help to eliminate some nodes).
Args:
decision_rule (list or tuple): A decision rule in the form of list of literals (binary variables representing the conditions of the tree).
Expand All @@ -329,7 +329,7 @@ def rectify(self, *, decision_rule, label):
"""
Tools.verbose("")
Tools.verbose("-------------- Rectify information:")
tree_decision_rule = self._tree.decision_rule_to_tree(decision_rule)
tree_decision_rule = self._tree.decision_rule_to_tree(conditions)
Tools.verbose("Desision Rule Number of nodes:", tree_decision_rule.n_nodes())
Tools.verbose("Model Number of nodes:", self._tree.n_nodes())
if label == 1:
Expand Down
2 changes: 1 addition & 1 deletion pyxai/sources/solvers/MAXSAT/OPENWBOSolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def solve(self, *, time_limit=0):
output_str = [line.split(" ") for line in p.stdout.split(os.linesep) if len(line) > 0 and line[0] == "v"]
if len(output_str) == 0:
return p.stderr, None, time_used

status = [line.split(" ")[1] for line in p.stdout.split(os.linesep) if len(line) > 0 and line[0] == "s"][0]
model = [int(lit) for lit in output_str[0] if lit != 'v' and lit != '']
return status, model, Explainer.TIMEOUT if status == "SATISFIABLE" else time_used
23 changes: 12 additions & 11 deletions pyxai/tests/functionality/Rectify.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import math


Tools.set_verbose(0)
#Tools.set_verbose(0)

import unittest
class TestRectify(unittest.TestCase):
Expand All @@ -20,8 +20,8 @@ def test_rectify_1(self):
explainer = Explainer.initialize(model, features_type=loan_types)

#Alice’s expertise can be represented by the formula T = ((x1 ∧ not x3) ⇒ y) ∧ (not x2 ⇒ not y) encoding her two decision rules
explainer.rectify(decision_rule=(1, -3), label=1) #(x1 ∧ not x3) ⇒ y
explainer.rectify(decision_rule=(-2, ), label=0) #not x2 ⇒ not y
explainer.rectify(conditions=(1, -3), label=1) #(x1 ∧ not x3) ⇒ y
explainer.rectify(conditions=(-2, ), label=0) #not x2 ⇒ not y

rectified_model = explainer.get_model().raw_data_for_CPP()

Expand Down Expand Up @@ -57,7 +57,7 @@ def test_rectify_2(self):
minimal = explainer.minimal_sufficient_reason()


explainer.rectify(decision_rule=minimal, label=1)
explainer.rectify(conditions=minimal, label=1)
rectified_model = explainer.get_model().raw_data_for_CPP()
self.assertEqual(rectified_model, (0, (1, (2, (5, (6, 1, 0), 1), 1), 1)))

Expand All @@ -84,7 +84,7 @@ def test_rectify_4(self):
#For him/her, the following classification rule must be obeyed:
#whenever the annual income of the client is lower than 30,
#the demand should be rejected
rectified_model = explainer.rectify(decision_rule=(-1, ), label=0)
rectified_model = explainer.rectify(conditions=(-1, ), label=0)

self.assertEqual(rectified_model.raw_data_for_CPP(), (0, (1, 0, (4, (3, 0, 1), 1))))

Expand All @@ -104,16 +104,17 @@ def test_rectify_3(self):

compas_types = {
"numerical": ["Number_of_Priors"],
"binary": ["Misdemeanor", "score_factor", "Age_Above_FourtyFive", "Age_Below_TwentyFive", "Female"],
"categorical": {"Origin*": ["African_American", "Asian", "Hispanic", "Native_American", "Other"]}
"binary": ["Misdemeanor", "score_factor", "Female"],
"categorical": {"Origin*": ["African_American", "Asian", "Hispanic", "Native_American", "Other"],
"Age*": ["Above_FourtyFive", "Below_TwentyFive"]}
}


explainer = Explainer.initialize(model, instance=instance, features_type=compas_types)
minimal_reason = explainer.sufficient_reason(n=1)
#print("explanation:", minimal_reason)
#print("explanation:", explainer.to_features(minimal_reason))
model = explainer.rectify(decision_rule=minimal_reason, label=1)
minimal_reason = explainer.minimal_sufficient_reason(n=1)
print("explanation:", minimal_reason)
print("explanation:", explainer.to_features(minimal_reason))
model = explainer.rectify(conditions=minimal_reason, label=1)

self.assertEqual(model.predict_instance(instance), 1)

Expand Down

0 comments on commit 409cd29

Please sign in to comment.