psyke 0.8.9.dev93__py3-none-any.whl → 0.8.14__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.
Potentially problematic release.
This version of psyke might be problematic. Click here for more details.
- psyke/extraction/hypercubic/hypercube.py +5 -3
- psyke/extraction/real/__init__.py +10 -19
- psyke/extraction/real/utils.py +2 -2
- psyke/extraction/trepan/__init__.py +2 -2
- psyke/hypercubepredictor.py +4 -2
- psyke/utils/logic.py +3 -7
- {psyke-0.8.9.dev93.dist-info → psyke-0.8.14.dist-info}/METADATA +1 -1
- {psyke-0.8.9.dev93.dist-info → psyke-0.8.14.dist-info}/RECORD +11 -11
- {psyke-0.8.9.dev93.dist-info → psyke-0.8.14.dist-info}/WHEEL +1 -1
- {psyke-0.8.9.dev93.dist-info → psyke-0.8.14.dist-info}/licenses/LICENSE +0 -0
- {psyke-0.8.9.dev93.dist-info → psyke-0.8.14.dist-info}/top_level.txt +0 -0
|
@@ -472,11 +472,13 @@ class RegressionCube(HyperCube):
|
|
|
472
472
|
|
|
473
473
|
def body(self, variables: dict[str, Var], ignore: list[str], unscale=None, normalization=None) -> Iterable[Struct]:
|
|
474
474
|
intercept = self.output.intercept_ if normalization is None else unscale(sum(
|
|
475
|
-
[-self.output.coef_[i] * normalization[name][0] / normalization[name][1] for i, name in
|
|
475
|
+
[-self.output.coef_.flatten()[i] * normalization[name][0] / normalization[name][1] for i, name in
|
|
476
476
|
enumerate(self.dimensions.keys())], self.output.intercept_), list(normalization.keys())[-1])
|
|
477
|
+
if isinstance(intercept, list):
|
|
478
|
+
intercept = intercept[0]
|
|
477
479
|
coefs = self.output.coef_ if normalization is None else [
|
|
478
|
-
self.output.coef_[i] / normalization[name][1] * normalization[list(normalization.keys())[-1]][1]
|
|
479
|
-
i, name in enumerate(self.dimensions.keys())
|
|
480
|
+
self.output.coef_.flatten()[i] / normalization[name][1] * normalization[list(normalization.keys())[-1]][1]
|
|
481
|
+
for i, name in enumerate(self.dimensions.keys())
|
|
480
482
|
]
|
|
481
483
|
return list(super().body(variables, ignore, unscale, normalization)) + [linear_function_creator(
|
|
482
484
|
list(variables.values()), [to_rounded_real(v) for v in coefs], to_rounded_real(intercept)
|
|
@@ -15,13 +15,11 @@ class REAL(PedagogicalExtractor):
|
|
|
15
15
|
"""
|
|
16
16
|
Explanator implementing Rule Extraction As Learning (REAL) algorithm, doi:10.1016/B978-1-55860-335-6.50013-1.
|
|
17
17
|
The algorithm is sensible to features' order in the provided dataset during extraction.
|
|
18
|
-
To make it reproducible the features are internally sorted (alphabetically).
|
|
19
18
|
"""
|
|
20
19
|
|
|
21
20
|
def __init__(self, predictor, discretization: Iterable[DiscreteFeature]):
|
|
22
21
|
super().__init__(predictor, discretization)
|
|
23
22
|
self._ruleset: IndexedRuleSet = IndexedRuleSet()
|
|
24
|
-
self._output_mapping = {}
|
|
25
23
|
|
|
26
24
|
@property
|
|
27
25
|
def n_rules(self):
|
|
@@ -31,7 +29,7 @@ class REAL(PedagogicalExtractor):
|
|
|
31
29
|
new_rule = self._rule_from_example(sample)
|
|
32
30
|
return any([new_rule in rule for rule in rules])
|
|
33
31
|
|
|
34
|
-
def
|
|
32
|
+
def _body(self, variables: dict[str, Var], rule: Rule) -> list[Struct]:
|
|
35
33
|
result = []
|
|
36
34
|
for predicates, truth_value in zip(rule.to_lists(), [True, False]):
|
|
37
35
|
for predicate in predicates:
|
|
@@ -40,27 +38,24 @@ class REAL(PedagogicalExtractor):
|
|
|
40
38
|
return result
|
|
41
39
|
|
|
42
40
|
def _create_clause(self, dataset: pd.DataFrame, variables: dict[str, Var], key: int, rule: Rule) -> Clause:
|
|
43
|
-
|
|
44
|
-
sorted(list(variables.values())),
|
|
45
|
-
str(sorted(list(set(dataset.iloc[:, -1])))[key]))
|
|
46
|
-
return clause(head, self._create_body(variables, rule))
|
|
41
|
+
return clause(create_head(dataset.columns[-1], list(variables.values()), key), self._body(variables, rule))
|
|
47
42
|
|
|
48
43
|
def _create_new_rule(self, sample: pd.Series) -> Rule:
|
|
49
44
|
rule = self._rule_from_example(sample)
|
|
50
45
|
return self._generalise(rule, sample)
|
|
51
46
|
|
|
52
47
|
def _create_ruleset(self, dataset: pd.DataFrame) -> IndexedRuleSet:
|
|
53
|
-
ruleset = IndexedRuleSet.create_indexed_ruleset(dataset)
|
|
54
|
-
for
|
|
48
|
+
ruleset = IndexedRuleSet.create_indexed_ruleset(sorted(set(dataset.iloc[:, -1])))
|
|
49
|
+
for _, sample in dataset.iloc[:, :-1].iterrows():
|
|
55
50
|
prediction = list(self.predictor.predict(sample.to_frame().transpose()))[0]
|
|
56
|
-
rules = ruleset.get(
|
|
51
|
+
rules = ruleset.get(prediction)
|
|
57
52
|
if not self._covers(sample, rules):
|
|
58
53
|
rules.append(self._create_new_rule(sample))
|
|
59
54
|
return ruleset.optimize()
|
|
60
55
|
|
|
61
|
-
def _create_theory(self, dataset: pd.DataFrame
|
|
56
|
+
def _create_theory(self, dataset: pd.DataFrame) -> MutableTheory:
|
|
62
57
|
theory = mutable_theory()
|
|
63
|
-
for key, rule in
|
|
58
|
+
for key, rule in self._ruleset.flatten():
|
|
64
59
|
variables = create_variable_list(self.discretization)
|
|
65
60
|
theory.assertZ(self._create_clause(dataset, variables, key, rule))
|
|
66
61
|
return theory
|
|
@@ -93,15 +88,14 @@ class REAL(PedagogicalExtractor):
|
|
|
93
88
|
|
|
94
89
|
def _internal_predict(self, sample: pd.Series):
|
|
95
90
|
x = [index for index, rule in self._ruleset.flatten() if REAL._rule_from_example(sample) in rule]
|
|
96
|
-
|
|
97
|
-
return reverse_mapping[x[0]] if len(x) > 0 else None
|
|
91
|
+
return x[0] if x else None
|
|
98
92
|
|
|
99
93
|
@staticmethod
|
|
100
94
|
def _rule_from_example(sample: pd.Series) -> Rule:
|
|
101
95
|
true_predicates, false_predicates = [], []
|
|
102
96
|
for feature, value in sample.items():
|
|
103
97
|
true_predicates.append(str(feature)) if value == 1 else false_predicates.append(str(feature))
|
|
104
|
-
return Rule(
|
|
98
|
+
return Rule(true_predicates, false_predicates)
|
|
105
99
|
|
|
106
100
|
def _subset(self, samples: pd.DataFrame, predicate: str) -> (pd.DataFrame, bool):
|
|
107
101
|
samples_0 = samples.copy()
|
|
@@ -112,11 +106,8 @@ class REAL(PedagogicalExtractor):
|
|
|
112
106
|
return samples_all, len(set(self.predictor.predict(samples_all))) == 1
|
|
113
107
|
|
|
114
108
|
def _extract(self, dataframe: pd.DataFrame) -> Theory:
|
|
115
|
-
# Order the dataset by column to preserve reproducibility.
|
|
116
|
-
dataframe = dataframe.sort_values(by=list(dataframe.columns.values), ascending=False)
|
|
117
|
-
self._output_mapping = {value: index for index, value in enumerate(sorted(set(dataframe.iloc[:, -1])))}
|
|
118
109
|
self._ruleset = self._get_or_set(HashableDataFrame(dataframe))
|
|
119
|
-
return self._create_theory(dataframe
|
|
110
|
+
return self._create_theory(dataframe)
|
|
120
111
|
|
|
121
112
|
def _predict(self, dataframe) -> Iterable:
|
|
122
113
|
return np.array([self._internal_predict(data.transpose()) for _, data in dataframe.iterrows()])
|
psyke/extraction/real/utils.py
CHANGED
|
@@ -49,5 +49,5 @@ class IndexedRuleSet(dict[int, list[Rule]]):
|
|
|
49
49
|
]
|
|
50
50
|
|
|
51
51
|
@staticmethod
|
|
52
|
-
def create_indexed_ruleset(
|
|
53
|
-
return IndexedRuleSet({
|
|
52
|
+
def create_indexed_ruleset(indices: Iterable) -> IndexedRuleSet:
|
|
53
|
+
return IndexedRuleSet({i: [] for i in indices})
|
|
@@ -73,10 +73,10 @@ class Trepan(PedagogicalExtractor):
|
|
|
73
73
|
splits.add(split)
|
|
74
74
|
return splits
|
|
75
75
|
|
|
76
|
-
def _create_theory(self, name: str
|
|
76
|
+
def _create_theory(self, name: str) -> MutableTheory:
|
|
77
77
|
theory = mutable_theory()
|
|
78
78
|
for node in self._root:
|
|
79
|
-
variables = create_variable_list(self.discretization
|
|
79
|
+
variables = create_variable_list(self.discretization)
|
|
80
80
|
theory.assertZ(
|
|
81
81
|
clause(
|
|
82
82
|
create_head(name, list(variables.values()), str(node.dominant)),
|
psyke/hypercubepredictor.py
CHANGED
|
@@ -45,9 +45,9 @@ class HyperCubePredictor(EvaluableModel):
|
|
|
45
45
|
idx = tree.query([list(row.values())], k=1)[1][0][0]
|
|
46
46
|
return HyperCubePredictor._get_cube_output(cubes[idx], row)
|
|
47
47
|
|
|
48
|
-
def _brute_predict_surface(self, row:
|
|
48
|
+
def _brute_predict_surface(self, row: pd.Series) -> GenericCube:
|
|
49
49
|
return min([(
|
|
50
|
-
cube.surface_distance(Point(list(row.keys()), list(row.values
|
|
50
|
+
cube.surface_distance(Point(list(row.keys()), list(row.values))), cube.volume(), cube
|
|
51
51
|
) for cube in self._hypercubes])[-1]
|
|
52
52
|
|
|
53
53
|
def _create_brute_tree(self, criterion: str = 'center', n: int = 2) -> (BallTree, list[GenericCube]):
|
|
@@ -76,6 +76,8 @@ class HyperCubePredictor(EvaluableModel):
|
|
|
76
76
|
return round(HyperCubePredictor._get_cube_output(cube, data), get_int_precision())
|
|
77
77
|
|
|
78
78
|
def _find_cube(self, data: dict[str, float]) -> GenericCube | None:
|
|
79
|
+
if not self._hypercubes:
|
|
80
|
+
return None
|
|
79
81
|
data = data.copy()
|
|
80
82
|
for dimension in self._dimensions_to_ignore:
|
|
81
83
|
if dimension in data:
|
psyke/utils/logic.py
CHANGED
|
@@ -123,12 +123,8 @@ def to_var(name: str) -> Var:
|
|
|
123
123
|
return var(name[0].upper() + name[1:])
|
|
124
124
|
|
|
125
125
|
|
|
126
|
-
def create_variable_list(features: list[DiscreteFeature], dataset: pd.DataFrame = None
|
|
127
|
-
if
|
|
128
|
-
features = sorted(features, key=lambda x: x.name)
|
|
129
|
-
dataset = sorted(dataset.columns[:-1]) if dataset is not None else None
|
|
130
|
-
else:
|
|
131
|
-
dataset = dataset.columns[:-1] if dataset is not None else None
|
|
126
|
+
def create_variable_list(features: list[DiscreteFeature], dataset: pd.DataFrame = None) -> dict[str, Var]:
|
|
127
|
+
dataset = dataset.columns[:-1] if dataset is not None else None
|
|
132
128
|
values = {feature.name: to_var(feature.name) for feature in features} \
|
|
133
129
|
if len(features) > 0 else {name: to_var(name) for name in dataset}
|
|
134
130
|
return values
|
|
@@ -325,4 +321,4 @@ def get_not_in_rule(min_included: bool = False, max_included: bool = True) -> Cl
|
|
|
325
321
|
parser = DEFAULT_CLAUSES_PARSER
|
|
326
322
|
theory = parser.parse_clauses(not_in_textual_rule(LE if min_included else L, GE if max_included else G),
|
|
327
323
|
operators=None)
|
|
328
|
-
return theory[0]
|
|
324
|
+
return theory[0]
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
psyke/__init__.py,sha256=V_sOXKt_5fYmNABwpveJd10u7Wy7A6wlLECBJY_ra_E,18634
|
|
2
|
-
psyke/hypercubepredictor.py,sha256=
|
|
2
|
+
psyke/hypercubepredictor.py,sha256=Pg8F2R_NHrNgFHx92s32BorYHMVvaxpEh4GtCsoyB2U,4620
|
|
3
3
|
psyke/clustering/__init__.py,sha256=36MokTVwwWR_-o0mesvXHaYEYVTK2pn2m0ZY4G3Y3qU,581
|
|
4
4
|
psyke/clustering/utils.py,sha256=S0YwCKyHVYp9qUAQVzCMrTwcQFPJ5TD14Jwn10DE-Z4,1616
|
|
5
5
|
psyke/clustering/cream/__init__.py,sha256=W6k7vdjuUdA_azYA4vb5JtpWrofhDJ0DbM2jsnRKzfw,2994
|
|
@@ -8,7 +8,7 @@ psyke/extraction/__init__.py,sha256=ziZ8T9eAOZjKipepE5_j1zfZgyFPONjW8MGERSk83nI,
|
|
|
8
8
|
psyke/extraction/cart/__init__.py,sha256=r2mDULg7oTHrIMPw9lqD6MyXhkkymP4r9PoGUKjAWCM,4569
|
|
9
9
|
psyke/extraction/cart/predictor.py,sha256=_YBedfyz4rGIBeNpN7OaL2BKWdF_5nuq8AlXkVfCtvk,3359
|
|
10
10
|
psyke/extraction/hypercubic/__init__.py,sha256=w_NmfSjh8fCWLDXVXpRLiAApq697cvUSPTgju-jtZCA,10620
|
|
11
|
-
psyke/extraction/hypercubic/hypercube.py,sha256=
|
|
11
|
+
psyke/extraction/hypercubic/hypercube.py,sha256=DlphGxbUHg4MePmpZm97PPw2GL8Ot2fypZBut-aTpwc,25794
|
|
12
12
|
psyke/extraction/hypercubic/strategy.py,sha256=X-roIsfcpJyMdo2px5JtbhP7-XE-zUNkaEK7XGXoWA8,1636
|
|
13
13
|
psyke/extraction/hypercubic/utils.py,sha256=D2FN5CCm_T3h23DmLFoTnIcFo7LvIq__ktl4hjUqkcA,1525
|
|
14
14
|
psyke/extraction/hypercubic/cosmik/__init__.py,sha256=XQUvOtMFpR0vMHYtwIVl3G626HMqN8Clt6BqNm4nvFs,1880
|
|
@@ -18,9 +18,9 @@ psyke/extraction/hypercubic/gridex/__init__.py,sha256=o7tNU3JH8AqA2PRj839-rPb6zh
|
|
|
18
18
|
psyke/extraction/hypercubic/gridrex/__init__.py,sha256=h9usK5tFqd6ngBmRydsgkfQ1jlcQKj2uG72Tr1puFHk,595
|
|
19
19
|
psyke/extraction/hypercubic/hex/__init__.py,sha256=553AZjOT9thfqDGtVDI6WtgYNex2Y6dg53cEyuf7Q80,4805
|
|
20
20
|
psyke/extraction/hypercubic/iter/__init__.py,sha256=9wE9pdEVNM9a9VfkNVKZjemFESyNJRoJPUF0AbitTsk,10054
|
|
21
|
-
psyke/extraction/real/__init__.py,sha256=
|
|
22
|
-
psyke/extraction/real/utils.py,sha256=
|
|
23
|
-
psyke/extraction/trepan/__init__.py,sha256=
|
|
21
|
+
psyke/extraction/real/__init__.py,sha256=t3wrY4dEmZK3PhGexxHh1bhlCr4vvZ1IS6vDZoHyZjw,5379
|
|
22
|
+
psyke/extraction/real/utils.py,sha256=4NNL15Eu7cmkG9b29GBP6CKgMTV1cmiJVS0k1MbWpIs,2148
|
|
23
|
+
psyke/extraction/trepan/__init__.py,sha256=1g9AXPgH6xrPUjFMFK7c7-DZ-AeGD7EUbF4U7WFSSsI,6553
|
|
24
24
|
psyke/extraction/trepan/utils.py,sha256=iSUJ1ooNQT_VO1KfBZuIUeUsyUbGdQf_pSEE87vMeQg,2320
|
|
25
25
|
psyke/schema/__init__.py,sha256=axv4ejZY0ItUwrC9IXb_yAhaQL5f1vwvXXmaIAHJmt0,26063
|
|
26
26
|
psyke/tuning/__init__.py,sha256=yd_ForFmHeYbtRXltY1fOa-mPJvpE6ijzg50M_8Sdxw,3649
|
|
@@ -29,12 +29,12 @@ psyke/tuning/orchid/__init__.py,sha256=s64iABbteik27CrRPHSVHNZX25JKlDu7YYjhseOiz
|
|
|
29
29
|
psyke/tuning/pedro/__init__.py,sha256=Q7Te3FWeLvJ7g2dkDraorUs6eRtxFgE9HEc3MshcATs,6648
|
|
30
30
|
psyke/utils/__init__.py,sha256=F-fgBT9CkthIwW8dDCuF5OoQDVMBNvIsZyvNqkgZNUA,1767
|
|
31
31
|
psyke/utils/dataframe.py,sha256=cPbCl_paACCtO0twCiHKUcEKIYiT89WDwQ-f5I9oKrg,6841
|
|
32
|
-
psyke/utils/logic.py,sha256=
|
|
32
|
+
psyke/utils/logic.py,sha256=P_hmhpRhpyCzWwOS1uOWGzvNAh6Eo10wbOBUQNZ_Rxo,12236
|
|
33
33
|
psyke/utils/metrics.py,sha256=Oo5BOonOSfo0qYsXWT5dmypZ7jiStByFC2MKEU0uMHg,2250
|
|
34
34
|
psyke/utils/plot.py,sha256=dE8JJ6tQ0Ezosid-r2jqAisREjFe5LqExRzsVi5Ns-c,7785
|
|
35
35
|
psyke/utils/sorted.py,sha256=C3CPW2JisND30BRk5c1sAAHs3Lb_wsRB2qZrYFuRnfM,678
|
|
36
|
-
psyke-0.8.
|
|
37
|
-
psyke-0.8.
|
|
38
|
-
psyke-0.8.
|
|
39
|
-
psyke-0.8.
|
|
40
|
-
psyke-0.8.
|
|
36
|
+
psyke-0.8.14.dist-info/licenses/LICENSE,sha256=KP9K6Hgezf_xdMFW7ORyKz9uA8Y8k52YJn292wcP-_E,11354
|
|
37
|
+
psyke-0.8.14.dist-info/METADATA,sha256=cwlsEje_1gui71I0iJ778f0RTM5Hf4sZA1Ztl6KXbDk,8390
|
|
38
|
+
psyke-0.8.14.dist-info/WHEEL,sha256=DnLRTWE75wApRYVsjgc6wsVswC54sMSJhAEd4xhDpBk,91
|
|
39
|
+
psyke-0.8.14.dist-info/top_level.txt,sha256=q1HglxOqqoIRukFtyis_ZNHczZg4gANRUPWkD7HAUTU,6
|
|
40
|
+
psyke-0.8.14.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|