ripple-down-rules 0.0.0__tar.gz → 0.0.1__tar.gz
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-0.0.0 → ripple_down_rules-0.0.1}/PKG-INFO +1 -1
- {ripple_down_rules-0.0.0 → ripple_down_rules-0.0.1}/pyproject.toml +1 -1
- {ripple_down_rules-0.0.0 → ripple_down_rules-0.0.1}/src/ripple_down_rules/datastructures/callable_expression.py +2 -2
- {ripple_down_rules-0.0.0 → ripple_down_rules-0.0.1}/src/ripple_down_rules/datastructures/table.py +8 -3
- {ripple_down_rules-0.0.0 → ripple_down_rules-0.0.1}/src/ripple_down_rules/rdr.py +9 -7
- {ripple_down_rules-0.0.0 → ripple_down_rules-0.0.1}/src/ripple_down_rules/rules.py +4 -0
- {ripple_down_rules-0.0.0 → ripple_down_rules-0.0.1}/src/ripple_down_rules/utils.py +19 -1
- {ripple_down_rules-0.0.0 → ripple_down_rules-0.0.1}/src/ripple_down_rules.egg-info/PKG-INFO +1 -1
- {ripple_down_rules-0.0.0 → ripple_down_rules-0.0.1}/test/test_json_serialization.py +11 -0
- {ripple_down_rules-0.0.0 → ripple_down_rules-0.0.1}/README.md +0 -0
- {ripple_down_rules-0.0.0 → ripple_down_rules-0.0.1}/setup.cfg +0 -0
- {ripple_down_rules-0.0.0 → ripple_down_rules-0.0.1}/src/ripple_down_rules/__init__.py +0 -0
- {ripple_down_rules-0.0.0 → ripple_down_rules-0.0.1}/src/ripple_down_rules/datasets.py +0 -0
- {ripple_down_rules-0.0.0 → ripple_down_rules-0.0.1}/src/ripple_down_rules/datastructures/__init__.py +0 -0
- {ripple_down_rules-0.0.0 → ripple_down_rules-0.0.1}/src/ripple_down_rules/datastructures/dataclasses.py +0 -0
- {ripple_down_rules-0.0.0 → ripple_down_rules-0.0.1}/src/ripple_down_rules/datastructures/enums.py +0 -0
- {ripple_down_rules-0.0.0 → ripple_down_rules-0.0.1}/src/ripple_down_rules/datastructures/generated/__init__.py +0 -0
- {ripple_down_rules-0.0.0 → ripple_down_rules-0.0.1}/src/ripple_down_rules/datastructures/generated/column/__init__.py +0 -0
- {ripple_down_rules-0.0.0 → ripple_down_rules-0.0.1}/src/ripple_down_rules/datastructures/generated/row/__init__.py +0 -0
- {ripple_down_rules-0.0.0 → ripple_down_rules-0.0.1}/src/ripple_down_rules/experts.py +0 -0
- {ripple_down_rules-0.0.0 → ripple_down_rules-0.0.1}/src/ripple_down_rules/failures.py +0 -0
- {ripple_down_rules-0.0.0 → ripple_down_rules-0.0.1}/src/ripple_down_rules/prompt.py +0 -0
- {ripple_down_rules-0.0.0 → ripple_down_rules-0.0.1}/src/ripple_down_rules.egg-info/SOURCES.txt +0 -0
- {ripple_down_rules-0.0.0 → ripple_down_rules-0.0.1}/src/ripple_down_rules.egg-info/dependency_links.txt +0 -0
- {ripple_down_rules-0.0.0 → ripple_down_rules-0.0.1}/src/ripple_down_rules.egg-info/requires.txt +0 -0
- {ripple_down_rules-0.0.0 → ripple_down_rules-0.0.1}/src/ripple_down_rules.egg-info/top_level.txt +0 -0
- {ripple_down_rules-0.0.0 → ripple_down_rules-0.0.1}/test/test_rdr.py +0 -0
- {ripple_down_rules-0.0.0 → ripple_down_rules-0.0.1}/test/test_rdr_alchemy.py +0 -0
- {ripple_down_rules-0.0.0 → ripple_down_rules-0.0.1}/test/test_relational_rdr.py +0 -0
- {ripple_down_rules-0.0.0 → ripple_down_rules-0.0.1}/test/test_relational_rdr_alchemy.py +0 -0
- {ripple_down_rules-0.0.0 → ripple_down_rules-0.0.1}/test/test_sql_model.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: ripple_down_rules
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.1
|
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
|
Project-URL: Homepage, https://github.com/AbdelrhmanBassiouny/ripple_down_rules
|
@@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
|
|
6
6
|
|
7
7
|
[project]
|
8
8
|
name = "ripple_down_rules"
|
9
|
-
version = "0.0.
|
9
|
+
version = "0.0.1"
|
10
10
|
description = "Implements the various versions of Ripple Down Rules (RDR) for knowledge representation and reasoning."
|
11
11
|
readme = "README.md"
|
12
12
|
authors = [{ name = "Abdelrhman Bassiouny", email = "abassiou@uni-bremen.de" }]
|
@@ -8,7 +8,7 @@ from sqlalchemy.orm import Session
|
|
8
8
|
from typing_extensions import Type, Optional, Any, List, Union, Tuple, Dict, Set
|
9
9
|
|
10
10
|
from .table import create_row, Row
|
11
|
-
from ..utils import SubclassJSONSerializer, get_full_class_name
|
11
|
+
from ..utils import SubclassJSONSerializer, get_full_class_name, get_type_from_string
|
12
12
|
|
13
13
|
|
14
14
|
class VariableVisitor(ast.NodeVisitor):
|
@@ -168,7 +168,7 @@ class CallableExpression(SubclassJSONSerializer):
|
|
168
168
|
|
169
169
|
@classmethod
|
170
170
|
def _from_json(cls, data: Dict[str, Any]) -> CallableExpression:
|
171
|
-
return cls(user_input=data["user_input"], conclusion_type=data["conclusion_type"])
|
171
|
+
return cls(user_input=data["user_input"], conclusion_type=get_type_from_string(data["conclusion_type"]))
|
172
172
|
|
173
173
|
|
174
174
|
def compile_expression_to_code(expression_tree: AST) -> Any:
|
{ripple_down_rules-0.0.0 → ripple_down_rules-0.0.1}/src/ripple_down_rules/datastructures/table.py
RENAMED
@@ -4,6 +4,7 @@ import os
|
|
4
4
|
import time
|
5
5
|
from abc import ABC
|
6
6
|
from collections import UserDict
|
7
|
+
from copy import deepcopy
|
7
8
|
from dataclasses import dataclass
|
8
9
|
from enum import Enum
|
9
10
|
|
@@ -77,6 +78,7 @@ class SubClassFactory:
|
|
77
78
|
parent_class_alias = cls.__name__ + "_"
|
78
79
|
imports = f"from {cls.__module__} import {cls.__name__} as {parent_class_alias}\n"
|
79
80
|
class_code = f"class {name}({parent_class_alias}):\n"
|
81
|
+
class_attributes = deepcopy(class_attributes) if class_attributes else {}
|
80
82
|
class_attributes.update({"_value_range": range_})
|
81
83
|
for key, value in class_attributes.items():
|
82
84
|
if value is not None:
|
@@ -245,12 +247,15 @@ class Row(UserDict, SubClassFactory, SubclassJSONSerializer):
|
|
245
247
|
return isinstance(instance, (dict, UserDict, Row)) or super().__instancecheck__(instance)
|
246
248
|
|
247
249
|
def to_json(self) -> Dict[str, Any]:
|
250
|
+
serializable = {k: v for k, v in self.items() if not k.startswith("_")}
|
251
|
+
serializable["_id"] = self.id
|
248
252
|
return {**SubclassJSONSerializer.to_json(self),
|
249
|
-
**{k: v.to_json() if isinstance(v, SubclassJSONSerializer) else v for k, v in
|
253
|
+
**{k: v.to_json() if isinstance(v, SubclassJSONSerializer) else v for k, v in serializable.items()}}
|
250
254
|
|
251
255
|
@classmethod
|
252
256
|
def _from_json(cls, data: Dict[str, Any]) -> Row:
|
253
|
-
|
257
|
+
id_ = data.pop("_id")
|
258
|
+
return cls(id_=id_, **data)
|
254
259
|
|
255
260
|
|
256
261
|
@dataclass
|
@@ -377,7 +382,7 @@ class Column(set, SubClassFactory, SubclassJSONSerializer):
|
|
377
382
|
|
378
383
|
@classmethod
|
379
384
|
def _from_json(cls, data: Dict[str, Any]) -> Column:
|
380
|
-
return cls({ColumnValue(
|
385
|
+
return cls({ColumnValue.from_json(v) for id_, v in data.items()})
|
381
386
|
|
382
387
|
|
383
388
|
def create_rows_from_dataframe(df: DataFrame, name: Optional[str] = None) -> List[Row]:
|
@@ -111,15 +111,17 @@ class RippleDownRules(ABC):
|
|
111
111
|
if animate_tree and self.start_rule.size > num_rules:
|
112
112
|
num_rules = self.start_rule.size
|
113
113
|
self.update_figures()
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
114
|
+
i += 1
|
115
|
+
all_pred = [1 if p == t else 0
|
116
|
+
for case, target in zip(cases, targets) for p, t in zip(self.classify(case), target)]
|
117
|
+
all_predicted = targets and sum(all_pred) == len(targets)
|
118
|
+
num_iter_reached = n_iter and i >= n_iter
|
119
|
+
stop_iterating = all_predicted or num_iter_reached
|
120
|
+
if stop_iterating:
|
121
|
+
break
|
120
122
|
print(f"Recall: {sum(all_recall) / len(all_recall)}")
|
121
123
|
print(f"Precision: {sum(all_precision) / len(all_precision)}")
|
122
|
-
print(f"Accuracy: {all_pred}/{
|
124
|
+
print(f"Accuracy: {all_pred}/{len(targets)}")
|
123
125
|
print(f"Finished training in {i} iterations")
|
124
126
|
if animate_tree:
|
125
127
|
plt.ioff()
|
@@ -114,6 +114,8 @@ class HasAlternativeRule:
|
|
114
114
|
Set the alternative rule of the rule. It is important that no rules should be retracted or changed,
|
115
115
|
only new rules should be added.
|
116
116
|
"""
|
117
|
+
if new_rule is None:
|
118
|
+
return
|
117
119
|
if self.furthest_alternative:
|
118
120
|
self.furthest_alternative[-1].alternative = new_rule
|
119
121
|
else:
|
@@ -139,6 +141,8 @@ class HasRefinementRule:
|
|
139
141
|
Set the refinement rule of the rule. It is important that no rules should be retracted or changed,
|
140
142
|
only new rules should be added.
|
141
143
|
"""
|
144
|
+
if new_rule is None:
|
145
|
+
return
|
142
146
|
new_rule.top_rule = self
|
143
147
|
if self.refinement:
|
144
148
|
self.refinement.alternative = new_rule
|
@@ -1,5 +1,6 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
+
import importlib
|
3
4
|
import logging
|
4
5
|
from abc import abstractmethod
|
5
6
|
from collections import UserDict
|
@@ -23,6 +24,17 @@ if TYPE_CHECKING:
|
|
23
24
|
matplotlib.use("Qt5Agg") # or "Qt5Agg", depending on availability
|
24
25
|
|
25
26
|
|
27
|
+
def get_type_from_string(type_path: str):
|
28
|
+
"""
|
29
|
+
Get a type from a string describing its path using the format "module_path.ClassName".
|
30
|
+
|
31
|
+
:param type_path: The path to the type.
|
32
|
+
"""
|
33
|
+
module_path, class_name = type_path.rsplit(".", 1)
|
34
|
+
module = importlib.import_module(module_path)
|
35
|
+
return getattr(module, class_name)
|
36
|
+
|
37
|
+
|
26
38
|
def get_full_class_name(cls):
|
27
39
|
"""
|
28
40
|
Returns the full name of a class, including the module name.
|
@@ -75,9 +87,15 @@ class SubclassJSONSerializer:
|
|
75
87
|
:param data: The json dict
|
76
88
|
:return: The correct instance of the subclass
|
77
89
|
"""
|
90
|
+
if data is None:
|
91
|
+
return None
|
92
|
+
if get_full_class_name(cls) == data["_type"]:
|
93
|
+
return cls._from_json(data)
|
78
94
|
for subclass in recursive_subclasses(SubclassJSONSerializer):
|
79
95
|
if get_full_class_name(subclass) == data["_type"]:
|
80
|
-
|
96
|
+
subclass_data = deepcopy(data)
|
97
|
+
subclass_data.pop("_type")
|
98
|
+
return subclass._from_json(subclass_data)
|
81
99
|
|
82
100
|
raise ValueError("Unknown type {}".format(data["_type"]))
|
83
101
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: ripple_down_rules
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.1
|
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
|
Project-URL: Homepage, https://github.com/AbdelrhmanBassiouny/ripple_down_rules
|
@@ -26,6 +26,14 @@ class TestJSONSerialization(TestCase):
|
|
26
26
|
with open(f"{self.cache_dir}/scrdr.json", "w") as f:
|
27
27
|
json.dump(scrdr_json, f, indent=4)
|
28
28
|
|
29
|
+
# load the json from the file
|
30
|
+
with open(f"{self.cache_dir}/scrdr.json", "r") as f:
|
31
|
+
scrdr_json = json.load(f)
|
32
|
+
scrdr = SingleClassRDR.from_json(scrdr_json)
|
33
|
+
for case, target in zip(self.all_cases, self.targets):
|
34
|
+
cat = scrdr.classify(case)
|
35
|
+
self.assertEqual(cat, target)
|
36
|
+
|
29
37
|
def get_fit_scrdr(self, draw_tree=False) -> SingleClassRDR:
|
30
38
|
filename = self.expert_answers_dir + "/scrdr_expert_answers_fit"
|
31
39
|
expert = Human(use_loaded_answers=True)
|
@@ -35,4 +43,7 @@ class TestJSONSerialization(TestCase):
|
|
35
43
|
case_queries = [CaseQuery(case, target=target) for case, target in zip(self.all_cases, self.targets)]
|
36
44
|
scrdr.fit(case_queries, expert=expert,
|
37
45
|
animate_tree=draw_tree)
|
46
|
+
for case, target in zip(self.all_cases, self.targets):
|
47
|
+
cat = scrdr.classify(case)
|
48
|
+
self.assertEqual(cat, target)
|
38
49
|
return scrdr
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{ripple_down_rules-0.0.0 → ripple_down_rules-0.0.1}/src/ripple_down_rules/datastructures/__init__.py
RENAMED
File without changes
|
File without changes
|
{ripple_down_rules-0.0.0 → ripple_down_rules-0.0.1}/src/ripple_down_rules/datastructures/enums.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{ripple_down_rules-0.0.0 → ripple_down_rules-0.0.1}/src/ripple_down_rules.egg-info/SOURCES.txt
RENAMED
File without changes
|
File without changes
|
{ripple_down_rules-0.0.0 → ripple_down_rules-0.0.1}/src/ripple_down_rules.egg-info/requires.txt
RENAMED
File without changes
|
{ripple_down_rules-0.0.0 → ripple_down_rules-0.0.1}/src/ripple_down_rules.egg-info/top_level.txt
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|