psyke 0.9.0.dev1__tar.gz → 0.9.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.
Potentially problematic release.
This version of psyke might be problematic. Click here for more details.
- {psyke-0.9.0.dev1/psyke.egg-info → psyke-0.9.1}/PKG-INFO +1 -1
- psyke-0.9.1/VERSION +1 -0
- psyke-0.9.1/psyke/extraction/__init__.py +26 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/psyke/extraction/cart/FairTree.py +9 -1
- {psyke-0.9.0.dev1 → psyke-0.9.1}/psyke/extraction/cart/FairTreePredictor.py +2 -8
- {psyke-0.9.0.dev1 → psyke-0.9.1}/psyke/extraction/real/__init__.py +11 -3
- {psyke-0.9.0.dev1 → psyke-0.9.1/psyke.egg-info}/PKG-INFO +1 -1
- psyke-0.9.0.dev1/VERSION +0 -1
- psyke-0.9.0.dev1/psyke/extraction/__init__.py +0 -51
- {psyke-0.9.0.dev1 → psyke-0.9.1}/LICENSE +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/MANIFEST.in +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/README.md +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/psyke/__init__.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/psyke/clustering/__init__.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/psyke/clustering/cream/__init__.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/psyke/clustering/exact/__init__.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/psyke/clustering/utils.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/psyke/extraction/cart/CartPredictor.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/psyke/extraction/cart/__init__.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/psyke/extraction/hypercubic/__init__.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/psyke/extraction/hypercubic/cosmik/__init__.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/psyke/extraction/hypercubic/creepy/__init__.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/psyke/extraction/hypercubic/divine/__init__.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/psyke/extraction/hypercubic/gridex/__init__.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/psyke/extraction/hypercubic/gridrex/__init__.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/psyke/extraction/hypercubic/hex/__init__.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/psyke/extraction/hypercubic/hypercube.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/psyke/extraction/hypercubic/iter/__init__.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/psyke/extraction/hypercubic/strategy.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/psyke/extraction/hypercubic/utils.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/psyke/extraction/real/utils.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/psyke/extraction/trepan/__init__.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/psyke/extraction/trepan/utils.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/psyke/hypercubepredictor.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/psyke/schema/__init__.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/psyke/tuning/__init__.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/psyke/tuning/crash/__init__.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/psyke/tuning/orchid/__init__.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/psyke/tuning/pedro/__init__.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/psyke/utils/__init__.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/psyke/utils/dataframe.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/psyke/utils/logic.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/psyke/utils/metrics.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/psyke/utils/plot.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/psyke/utils/sorted.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/psyke.egg-info/SOURCES.txt +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/psyke.egg-info/dependency_links.txt +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/psyke.egg-info/not-zip-safe +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/psyke.egg-info/requires.txt +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/psyke.egg-info/top_level.txt +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/pyproject.toml +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/setup.cfg +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/setup.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/test/psyke/__init__.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/test/psyke/clustering/__init__.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/test/psyke/extraction/__init__.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/test/psyke/extraction/cart/__init__.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/test/psyke/extraction/cart/test_cart.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/test/psyke/extraction/cart/test_simplified_cart.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/test/psyke/extraction/hypercubic/__init__.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/test/psyke/extraction/hypercubic/gridex/__init__.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/test/psyke/extraction/hypercubic/gridex/test_gridex.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/test/psyke/extraction/hypercubic/iter/__init__.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/test/psyke/extraction/hypercubic/iter/test_iter.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/test/psyke/extraction/hypercubic/test_hypercube.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/test/psyke/extraction/real/__init__.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/test/psyke/extraction/real/test_real.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/test/psyke/extraction/real/test_rule.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/test/psyke/extraction/trepan/__init__.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/test/psyke/extraction/trepan/test_node.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/test/psyke/extraction/trepan/test_split.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/test/psyke/extraction/trepan/test_trepan.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/test/psyke/utils/__init__.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/test/psyke/utils/test_prune.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/test/psyke/utils/test_simplify.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/test/psyke/utils/test_simplify_formatter.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/test/resources/__init__.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/test/resources/datasets/__init__.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/test/resources/predictors/__init__.py +0 -0
- {psyke-0.9.0.dev1 → psyke-0.9.1}/test/resources/tests/__init__.py +0 -0
psyke-0.9.1/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.9.1
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from abc import ABC
|
|
2
|
+
from collections import Iterable
|
|
3
|
+
|
|
4
|
+
import pandas as pd
|
|
5
|
+
from tuprolog.theory import Theory
|
|
6
|
+
|
|
7
|
+
from psyke import Extractor
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class PedagogicalExtractor(Extractor, ABC):
|
|
11
|
+
|
|
12
|
+
def __init__(self, predictor, discretization=None, normalization=None):
|
|
13
|
+
Extractor.__init__(self, predictor=predictor, discretization=discretization, normalization=normalization)
|
|
14
|
+
|
|
15
|
+
def _substitute_output(self, dataframe: pd.DataFrame) -> pd.DataFrame:
|
|
16
|
+
new_y = pd.DataFrame(self.predictor.predict(dataframe.iloc[:, :-1])).set_index(dataframe.index)
|
|
17
|
+
data = dataframe.iloc[:, :-1].copy().join(new_y)
|
|
18
|
+
data.columns = dataframe.columns
|
|
19
|
+
return data
|
|
20
|
+
|
|
21
|
+
def extract(self, dataframe: pd.DataFrame) -> Theory:
|
|
22
|
+
self.theory = self._extract(self._substitute_output(dataframe))
|
|
23
|
+
return self.theory
|
|
24
|
+
|
|
25
|
+
def _extract(self, dataframe: pd.DataFrame) -> Theory:
|
|
26
|
+
raise NotImplementedError('extract')
|
|
@@ -72,12 +72,20 @@ class FairTree:
|
|
|
72
72
|
right = self._grow_tree(X[right_idxs], y[right_idxs], depth + 1)
|
|
73
73
|
return Node(best_feature, best_threshold, left, right)
|
|
74
74
|
|
|
75
|
+
@staticmethod
|
|
76
|
+
def generate_thresholds(X, y):
|
|
77
|
+
sorted_indices = np.argsort(X)
|
|
78
|
+
X = np.array(X)[sorted_indices]
|
|
79
|
+
y = np.array(y)[sorted_indices]
|
|
80
|
+
return np.array([(X[i] + X[i - 1]) / 2.0 for i in range(1, len(X)) if y[i] != y[i - 1]])
|
|
81
|
+
|
|
75
82
|
def _best_split(self, X, y):
|
|
76
83
|
best_gain = -float('inf')
|
|
77
84
|
split_idx, split_threshold = None, None
|
|
78
85
|
|
|
79
86
|
for feature in [feature for feature in X.columns if feature not in self.protected_attr]:
|
|
80
|
-
for threshold in np.unique(np.quantile(X[feature], np.linspace(0, 1, num=25))):
|
|
87
|
+
# for threshold in np.unique(np.quantile(X[feature], np.linspace(0, 1, num=25))):
|
|
88
|
+
for threshold in self.generate_thresholds(X[feature], y):
|
|
81
89
|
left_idxs = X[feature] <= threshold
|
|
82
90
|
right_idxs = X[feature] > threshold
|
|
83
91
|
|
|
@@ -1,15 +1,9 @@
|
|
|
1
1
|
import copy
|
|
2
|
-
from collections import Iterable
|
|
3
2
|
from typing import Union, Any
|
|
4
|
-
import pandas as pd
|
|
5
|
-
from sklearn.tree import DecisionTreeClassifier, DecisionTreeRegressor
|
|
6
|
-
from tuprolog.core import clause, Var, Struct
|
|
7
|
-
from tuprolog.theory import Theory, mutable_theory
|
|
8
3
|
|
|
9
4
|
from psyke.extraction.cart import FairTreeClassifier, FairTreeRegressor, LeafSequence, LeafConstraints
|
|
10
5
|
from psyke.extraction.cart.CartPredictor import CartPredictor
|
|
11
|
-
from psyke.schema import LessThan, GreaterThan, SchemaException,
|
|
12
|
-
from psyke.utils.logic import create_variable_list, create_head, create_term
|
|
6
|
+
from psyke.schema import LessThan, GreaterThan, SchemaException, Value
|
|
13
7
|
|
|
14
8
|
|
|
15
9
|
class FairTreePredictor(CartPredictor):
|
|
@@ -17,7 +11,7 @@ class FairTreePredictor(CartPredictor):
|
|
|
17
11
|
A wrapper for fair decision and regression trees of psyke.
|
|
18
12
|
"""
|
|
19
13
|
|
|
20
|
-
def __init__(self, predictor: Union[FairTreeClassifier, FairTreeRegressor] =
|
|
14
|
+
def __init__(self, predictor: Union[FairTreeClassifier, FairTreeRegressor] = FairTreeClassifier(),
|
|
21
15
|
discretization=None, normalization=None):
|
|
22
16
|
super().__init__(predictor, discretization, normalization)
|
|
23
17
|
|
|
@@ -19,6 +19,7 @@ class REAL(PedagogicalExtractor):
|
|
|
19
19
|
|
|
20
20
|
def __init__(self, predictor, discretization: Iterable[DiscreteFeature]):
|
|
21
21
|
super().__init__(predictor, discretization)
|
|
22
|
+
self._ignore_feature = []
|
|
22
23
|
self._ruleset: IndexedRuleSet = IndexedRuleSet()
|
|
23
24
|
|
|
24
25
|
@property
|
|
@@ -87,13 +88,20 @@ class REAL(PedagogicalExtractor):
|
|
|
87
88
|
return self._create_ruleset(dataset)
|
|
88
89
|
|
|
89
90
|
def _internal_predict(self, sample: pd.Series):
|
|
90
|
-
x = [index for index, rule in self._ruleset.flatten() if
|
|
91
|
+
x = [index for index, rule in self._ruleset.flatten() if self._rule_from_example(sample) in rule]
|
|
91
92
|
return x[0] if x else None
|
|
92
93
|
|
|
93
|
-
|
|
94
|
-
|
|
94
|
+
def make_fair(self, features: Iterable[str]):
|
|
95
|
+
self._ignore_feature = [list(i.admissible_values.keys()) for i in self.discretization if i.name in features] \
|
|
96
|
+
if self.discretization else [features]
|
|
97
|
+
self._ignore_feature = [feature for features in self._ignore_feature for feature in features]
|
|
98
|
+
self._get_or_set.cache_clear()
|
|
99
|
+
|
|
100
|
+
def _rule_from_example(self, sample: pd.Series) -> Rule:
|
|
95
101
|
true_predicates, false_predicates = [], []
|
|
96
102
|
for feature, value in sample.items():
|
|
103
|
+
if feature in self._ignore_feature:
|
|
104
|
+
continue
|
|
97
105
|
true_predicates.append(str(feature)) if value == 1 else false_predicates.append(str(feature))
|
|
98
106
|
return Rule(true_predicates, false_predicates)
|
|
99
107
|
|
psyke-0.9.0.dev1/VERSION
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
0.9.0.dev1
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
from abc import ABC
|
|
2
|
-
from collections import Iterable
|
|
3
|
-
|
|
4
|
-
import pandas as pd
|
|
5
|
-
from tuprolog.theory import Theory
|
|
6
|
-
|
|
7
|
-
from psyke import Extractor
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class PedagogicalExtractor(Extractor, ABC):
|
|
11
|
-
|
|
12
|
-
def __init__(self, predictor, discretization=None, normalization=None):
|
|
13
|
-
Extractor.__init__(self, predictor=predictor, discretization=discretization, normalization=normalization)
|
|
14
|
-
|
|
15
|
-
def _substitute_output(self, dataframe: pd.DataFrame) -> pd.DataFrame:
|
|
16
|
-
new_y = pd.DataFrame(self.predictor.predict(dataframe.iloc[:, :-1])).set_index(dataframe.index)
|
|
17
|
-
data = dataframe.iloc[:, :-1].copy().join(new_y)
|
|
18
|
-
data.columns = dataframe.columns
|
|
19
|
-
return data
|
|
20
|
-
|
|
21
|
-
def extract(self, dataframe: pd.DataFrame) -> Theory:
|
|
22
|
-
self.theory = self._extract(self._substitute_output(dataframe))
|
|
23
|
-
return self.theory
|
|
24
|
-
|
|
25
|
-
def _extract(self, dataframe: pd.DataFrame) -> Theory:
|
|
26
|
-
raise NotImplementedError('extract')
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
class FairExtractor(PedagogicalExtractor, ABC):
|
|
30
|
-
|
|
31
|
-
def __init__(self, extractor: Extractor, features: Iterable):
|
|
32
|
-
super().__init__(extractor.predictor, extractor.discretization, extractor.normalization)
|
|
33
|
-
self.features = features
|
|
34
|
-
self.extractor = extractor
|
|
35
|
-
# self.make_fair()
|
|
36
|
-
|
|
37
|
-
# def extract(self, dataframe: pd.DataFrame) -> Theory:
|
|
38
|
-
# self.theory = self.extractor.extract(dataframe)
|
|
39
|
-
# return self.theory
|
|
40
|
-
|
|
41
|
-
# def predict_why(self, data: dict[str, float], verbose: bool = True):
|
|
42
|
-
# self.extractor.predict_why(data, verbose)
|
|
43
|
-
|
|
44
|
-
# def predict_counter(self, data: dict[str, float], verbose: bool = True, only_first: bool = True):
|
|
45
|
-
# self.extractor.predict_counter(data, verbose, only_first)
|
|
46
|
-
|
|
47
|
-
# def _predict(self, dataframe: pd.DataFrame) -> Iterable:
|
|
48
|
-
# return self.extractor.predict(dataframe)
|
|
49
|
-
|
|
50
|
-
# def _brute_predict(self, dataframe: pd.DataFrame, criterion: str = 'corner', n: int = 2) -> Iterable:
|
|
51
|
-
# return self.extractor.brute_predict(dataframe, criterion, n)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|