ripple-down-rules 0.1.0__py3-none-any.whl → 0.1.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ripple_down_rules/datastructures/case.py +1 -0
- ripple_down_rules/rdr.py +12 -16
- ripple_down_rules/utils.py +16 -3
- {ripple_down_rules-0.1.0.dist-info → ripple_down_rules-0.1.2.dist-info}/METADATA +1 -1
- {ripple_down_rules-0.1.0.dist-info → ripple_down_rules-0.1.2.dist-info}/RECORD +8 -8
- {ripple_down_rules-0.1.0.dist-info → ripple_down_rules-0.1.2.dist-info}/WHEEL +0 -0
- {ripple_down_rules-0.1.0.dist-info → ripple_down_rules-0.1.2.dist-info}/licenses/LICENSE +0 -0
- {ripple_down_rules-0.1.0.dist-info → ripple_down_rules-0.1.2.dist-info}/top_level.txt +0 -0
@@ -214,6 +214,7 @@ def create_case(obj: Any, recursion_idx: int = 0, max_recursion_idx: int = 0,
|
|
214
214
|
:param parent_is_iterable: Boolean indicating whether the parent object is iterable or not.
|
215
215
|
:return: The case that represents the object.
|
216
216
|
"""
|
217
|
+
obj_name = obj_name or obj.__class__.__name__
|
217
218
|
if isinstance(obj, DataFrame):
|
218
219
|
return create_cases_from_dataframe(obj, obj_name)
|
219
220
|
if isinstance(obj, Case):
|
ripple_down_rules/rdr.py
CHANGED
@@ -132,12 +132,7 @@ class RippleDownRules(SubclassJSONSerializer, ABC):
|
|
132
132
|
for pred_key, pred_value in pred_cat.items():
|
133
133
|
if pred_key not in target:
|
134
134
|
continue
|
135
|
-
# if is_iterable(pred_value):
|
136
|
-
# print(pred_value, target[pred_key])
|
137
|
-
# precision.extend([v in make_set(target[pred_key]) for v in make_set(pred_value)])
|
138
135
|
precision.extend([v in make_set(target[pred_key]) for v in make_set(pred_value)])
|
139
|
-
# else:
|
140
|
-
# precision.append(pred_value == target[pred_key])
|
141
136
|
for target_key, target_value in target.items():
|
142
137
|
if target_key not in pred_cat:
|
143
138
|
recall.append(False)
|
@@ -146,7 +141,6 @@ class RippleDownRules(SubclassJSONSerializer, ABC):
|
|
146
141
|
recall.extend([v in pred_cat[target_key] for v in target_value])
|
147
142
|
else:
|
148
143
|
recall.append(target_value == pred_cat[target_key])
|
149
|
-
print(f"Precision: {precision}, Recall: {recall}")
|
150
144
|
else:
|
151
145
|
if isinstance(target, dict):
|
152
146
|
target = list(target.values())
|
@@ -169,9 +163,9 @@ class RippleDownRules(SubclassJSONSerializer, ABC):
|
|
169
163
|
Update the figures of the classifier.
|
170
164
|
"""
|
171
165
|
if isinstance(self, GeneralRDR):
|
172
|
-
for i, (
|
166
|
+
for i, (rdr_name, rdr) in enumerate(self.start_rules_dict.items()):
|
173
167
|
if not rdr.fig:
|
174
|
-
rdr.fig = plt.figure(f"Rule {i}: {
|
168
|
+
rdr.fig = plt.figure(f"Rule {i}: {rdr_name}")
|
175
169
|
draw_tree(rdr.start_rule, rdr.fig)
|
176
170
|
else:
|
177
171
|
if not self.fig:
|
@@ -214,7 +208,7 @@ class RDRWithCodeWriter(RippleDownRules, ABC):
|
|
214
208
|
f.write(self._get_imports() + "\n\n")
|
215
209
|
f.write(func_def)
|
216
210
|
f.write(f"{' ' * 4}if not isinstance(case, Case):\n"
|
217
|
-
f"{' ' * 4} case = create_case(case,
|
211
|
+
f"{' ' * 4} case = create_case(case, max_recursion_idx=3)\n""")
|
218
212
|
self.write_rules_as_source_code_to_file(self.start_rule, f, " " * 4)
|
219
213
|
|
220
214
|
@property
|
@@ -235,6 +229,11 @@ class RDRWithCodeWriter(RippleDownRules, ABC):
|
|
235
229
|
if self.conclusion_type.__module__ != "builtins":
|
236
230
|
imports += f"from {self.conclusion_type.__module__} import {self.conclusion_type.__name__}\n"
|
237
231
|
imports += "from ripple_down_rules.datastructures import Case, create_case\n"
|
232
|
+
for rule in [self.start_rule] + list(self.start_rule.descendants):
|
233
|
+
if rule.conditions:
|
234
|
+
if rule.conditions.scope is not None and len(rule.conditions.scope) > 0:
|
235
|
+
for k, v in rule.conditions.scope.items():
|
236
|
+
imports += f"from {v.__module__} import {v.__name__}\n"
|
238
237
|
return imports
|
239
238
|
|
240
239
|
def get_rdr_classifier_from_python_file(self, package_name) -> Callable[[Any], Any]:
|
@@ -246,11 +245,7 @@ class RDRWithCodeWriter(RippleDownRules, ABC):
|
|
246
245
|
|
247
246
|
@property
|
248
247
|
def generated_python_file_name(self) -> str:
|
249
|
-
return f"{self.
|
250
|
-
|
251
|
-
@property
|
252
|
-
def python_file_name(self):
|
253
|
-
return f"{self.start_rule.conclusion.__name__.lower()}_rdr"
|
248
|
+
return f"{self.start_rule.corner_case._name.lower()}_{self.attribute_name}_rdr"
|
254
249
|
|
255
250
|
@property
|
256
251
|
def case_type(self) -> Type:
|
@@ -485,6 +480,7 @@ class MultiClassRDR(RDRWithCodeWriter):
|
|
485
480
|
self.start_rule.conditions = conditions
|
486
481
|
self.start_rule.conclusion = case_query.target
|
487
482
|
self.start_rule.corner_case = case_query.case
|
483
|
+
self.start_rule.conclusion_name = case_query.attribute_name
|
488
484
|
|
489
485
|
@property
|
490
486
|
def last_top_rule(self) -> Optional[MultiClassTopRule]:
|
@@ -866,7 +862,7 @@ class GeneralRDR(RippleDownRules):
|
|
866
862
|
f.write("\n\n")
|
867
863
|
f.write(func_def)
|
868
864
|
f.write(f"{' ' * 4}if not isinstance(case, Case):\n"
|
869
|
-
f"{' ' * 4} case = create_case(case,
|
865
|
+
f"{' ' * 4} case = create_case(case, max_recursion_idx=3)\n""")
|
870
866
|
f.write(f"{' ' * 4}return GeneralRDR._classify(classifiers_dict, case)\n")
|
871
867
|
|
872
868
|
@property
|
@@ -888,7 +884,7 @@ class GeneralRDR(RippleDownRules):
|
|
888
884
|
|
889
885
|
@property
|
890
886
|
def generated_python_file_name(self) -> str:
|
891
|
-
return f"{self.
|
887
|
+
return f"{self.start_rule.corner_case._name.lower()}_rdr"
|
892
888
|
|
893
889
|
@property
|
894
890
|
def conclusion_type_hint(self) -> str:
|
ripple_down_rules/utils.py
CHANGED
@@ -27,7 +27,14 @@ if TYPE_CHECKING:
|
|
27
27
|
matplotlib.use("Qt5Agg") # or "Qt5Agg", depending on availability
|
28
28
|
|
29
29
|
|
30
|
-
def serialize_dataclass(obj: Any) -> Dict:
|
30
|
+
def serialize_dataclass(obj: Any) -> Union[Dict, Any]:
|
31
|
+
"""
|
32
|
+
Recursively serialize a dataclass to a dictionary. If the dataclass contains any nested dataclasses, they will be
|
33
|
+
serialized as well. If the object is not a dataclass, it will be returned as is.
|
34
|
+
|
35
|
+
:param obj: The dataclass to serialize.
|
36
|
+
:return: The serialized dataclass as a dictionary or the object itself if it is not a dataclass.
|
37
|
+
"""
|
31
38
|
|
32
39
|
def recursive_convert(obj):
|
33
40
|
if is_dataclass(obj):
|
@@ -39,8 +46,6 @@ def serialize_dataclass(obj: Any) -> Dict:
|
|
39
46
|
return [recursive_convert(item) for item in obj]
|
40
47
|
elif isinstance(obj, dict):
|
41
48
|
return {k: recursive_convert(v) for k, v in obj.items()}
|
42
|
-
elif hasattr(obj, "__module__") and hasattr(obj, "__name__"):
|
43
|
-
return {'_type': get_full_class_name(obj.__class__)}
|
44
49
|
else:
|
45
50
|
return obj
|
46
51
|
|
@@ -48,6 +53,14 @@ def serialize_dataclass(obj: Any) -> Dict:
|
|
48
53
|
|
49
54
|
|
50
55
|
def deserialize_dataclass(data: dict) -> Any:
|
56
|
+
"""
|
57
|
+
Recursively deserialize a dataclass from a dictionary, if the dictionary contains a key "__dataclass__" (Most likely
|
58
|
+
created by the serialize_dataclass function), it will be treated as a dataclass and deserialized accordingly,
|
59
|
+
otherwise it will be returned as is.
|
60
|
+
|
61
|
+
:param data: The dictionary to deserialize.
|
62
|
+
:return: The deserialized dataclass.
|
63
|
+
"""
|
51
64
|
def recursive_load(obj):
|
52
65
|
if isinstance(obj, dict) and "__dataclass__" in obj:
|
53
66
|
module_name, class_name = obj["__dataclass__"].rsplit(".", 1)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: ripple_down_rules
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.2
|
4
4
|
Summary: Implements the various versions of Ripple Down Rules (RDR) for knowledge representation and reasoning.
|
5
5
|
Author-email: Abdelrhman Bassiouny <abassiou@uni-bremen.de>
|
6
6
|
License: GNU GENERAL PUBLIC LICENSE
|
@@ -4,17 +4,17 @@ ripple_down_rules/experts.py,sha256=Xz1U1Tdq7jrFlcVuSusaMB241AG9TEs7q101i59Xijs,
|
|
4
4
|
ripple_down_rules/failures.py,sha256=E6ajDUsw3Blom8eVLbA7d_Qnov2conhtZ0UmpQ9ZtSE,302
|
5
5
|
ripple_down_rules/helpers.py,sha256=AhqerAQoCdSovJ7SdQrNtAI_hYagKpLsy2nJQGA0bl0,1062
|
6
6
|
ripple_down_rules/prompt.py,sha256=z6KddZOsNiStptgCRNh2OVHHuH6Ooa2f-nsrgJH1qJ8,6311
|
7
|
-
ripple_down_rules/rdr.py,sha256=
|
7
|
+
ripple_down_rules/rdr.py,sha256=NXVYIflUxcDzC5DDrK-l_ZT-sBmUV1ZgkznshSsJZYc,43508
|
8
8
|
ripple_down_rules/rdr_decorators.py,sha256=8SclpceI3EtrsbuukWJu8HGLh7Q1ZCgYGLX-RPlG-w0,2018
|
9
9
|
ripple_down_rules/rules.py,sha256=aM3Im4ePuFDlkuD2EKRtiVmYgoQ_sxlwcbzrDKqXAfs,14578
|
10
|
-
ripple_down_rules/utils.py,sha256=
|
10
|
+
ripple_down_rules/utils.py,sha256=9gPnRWlLye7FettI2QRWJx8oU9z3ckwdO5jopXK8b-8,24290
|
11
11
|
ripple_down_rules/datastructures/__init__.py,sha256=zpmiYm4WkwNHaGdTIfacS7llN5d2xyU6U-saH_TpydI,103
|
12
12
|
ripple_down_rules/datastructures/callable_expression.py,sha256=ac2TaMr0hiRX928GMcr3oTQic8KXXO4syLw4KV-Iehs,10515
|
13
|
-
ripple_down_rules/datastructures/case.py,sha256=
|
13
|
+
ripple_down_rules/datastructures/case.py,sha256=3Pl07jmYn94wdCVTaRZDmBPgyAsN1TjebvrE6-68MVU,13606
|
14
14
|
ripple_down_rules/datastructures/dataclasses.py,sha256=AI-wqNy8y9QPg6lov0P-c5b8JXemuM4X62tIRhW-Gqs,4231
|
15
15
|
ripple_down_rules/datastructures/enums.py,sha256=l0Eu-TeJ6qB2XHoJycXmUgLw-3yUebQ8SsEbW8bBZdM,4543
|
16
|
-
ripple_down_rules-0.1.
|
17
|
-
ripple_down_rules-0.1.
|
18
|
-
ripple_down_rules-0.1.
|
19
|
-
ripple_down_rules-0.1.
|
20
|
-
ripple_down_rules-0.1.
|
16
|
+
ripple_down_rules-0.1.2.dist-info/licenses/LICENSE,sha256=ixuiBLtpoK3iv89l7ylKkg9rs2GzF9ukPH7ynZYzK5s,35148
|
17
|
+
ripple_down_rules-0.1.2.dist-info/METADATA,sha256=3-IzXML9BpPYbOlnZmg0eOXRJvMcFH7efnNecCOZ-XE,42518
|
18
|
+
ripple_down_rules-0.1.2.dist-info/WHEEL,sha256=pxyMxgL8-pra_rKaQ4drOZAegBVuX-G_4nRHjjgWbmo,91
|
19
|
+
ripple_down_rules-0.1.2.dist-info/top_level.txt,sha256=VeoLhEhyK46M1OHwoPbCQLI1EifLjChqGzhQ6WEUqeM,18
|
20
|
+
ripple_down_rules-0.1.2.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|