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.

@@ -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] for
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 _create_body(self, variables: dict[str, Var], rule: Rule) -> list[Struct]:
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
- head = create_head(dataset.columns[-1],
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 index, sample in dataset.iloc[:, :-1].iterrows():
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(self._output_mapping[prediction])
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, ruleset: IndexedRuleSet) -> MutableTheory:
56
+ def _create_theory(self, dataset: pd.DataFrame) -> MutableTheory:
62
57
  theory = mutable_theory()
63
- for key, rule in ruleset.flatten():
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
- reverse_mapping = dict((v, k) for k, v in self._output_mapping.items())
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(sorted(true_predicates), sorted(false_predicates))
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, self._ruleset)
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()])
@@ -49,5 +49,5 @@ class IndexedRuleSet(dict[int, list[Rule]]):
49
49
  ]
50
50
 
51
51
  @staticmethod
52
- def create_indexed_ruleset(dataset: pd.DataFrame) -> IndexedRuleSet:
53
- return IndexedRuleSet({index: [] for index, _ in enumerate(set(dataset.iloc[:, -1]))})
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, sort: bool = True) -> MutableTheory:
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, sort=sort)
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)),
@@ -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: dict[str, float]) -> GenericCube:
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()))), cube.volume(), cube
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, sort: bool = True) -> dict[str, Var]:
127
- if sort:
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,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: psyke
3
- Version: 0.8.9.dev93
3
+ Version: 0.8.14
4
4
  Summary: Python-based implementation of PSyKE, i.e. a Platform for Symbolic Knowledge Extraction
5
5
  Home-page: https://github.com/psykei/psyke-python
6
6
  Author: Matteo Magnini
@@ -1,5 +1,5 @@
1
1
  psyke/__init__.py,sha256=V_sOXKt_5fYmNABwpveJd10u7Wy7A6wlLECBJY_ra_E,18634
2
- psyke/hypercubepredictor.py,sha256=MlSRLky6J1I07qKcH98c9WvEjFHGyBiz_LU9W_oDnqs,4572
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=GKjplRl34BegrA3JclvlkrL7hXftdUUMXndmRFFoJic,25697
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=fFqiwgWTpu5Jx9lz5CdSfs1QyqWYFLQDG7tc5M6Q7UM,6065
22
- psyke/extraction/real/utils.py,sha256=eHGU-Y0inn_8jrk9lMcuRUKXpsTkI-s_myXSWz4bALQ,2190
23
- psyke/extraction/trepan/__init__.py,sha256=KpZpk0btCWV4bS-DOmpgpYscSQ5FEMyP54ekm7ZedME,6583
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=7bbW6qcKof5PlqoQ0n5Kt3Obcot-KqGAvpE8rMXvEPE,12419
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.9.dev93.dist-info/licenses/LICENSE,sha256=KP9K6Hgezf_xdMFW7ORyKz9uA8Y8k52YJn292wcP-_E,11354
37
- psyke-0.8.9.dev93.dist-info/METADATA,sha256=j5s2tda9j6R5nmDATTaqmjYCObNgGkaL7mUDOhFZqEM,8395
38
- psyke-0.8.9.dev93.dist-info/WHEEL,sha256=pxyMxgL8-pra_rKaQ4drOZAegBVuX-G_4nRHjjgWbmo,91
39
- psyke-0.8.9.dev93.dist-info/top_level.txt,sha256=q1HglxOqqoIRukFtyis_ZNHczZg4gANRUPWkD7HAUTU,6
40
- psyke-0.8.9.dev93.dist-info/RECORD,,
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,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (79.0.0)
2
+ Generator: setuptools (80.4.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5