rulelearn-ripper-interactive 0.2.3__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.
Files changed (73) hide show
  1. rulelearn_ri/__init__.py +6 -0
  2. rulelearn_ri/algorithms/__init__.py +0 -0
  3. rulelearn_ri/algorithms/r2n/__init__.py +0 -0
  4. rulelearn_ri/algorithms/r2n/base.py +28 -0
  5. rulelearn_ri/algorithms/r2n/functions.py +25 -0
  6. rulelearn_ri/algorithms/r2n/mask.py +58 -0
  7. rulelearn_ri/algorithms/r2n/preprocessing_layers.py +192 -0
  8. rulelearn_ri/algorithms/r2n/r2n_algo.py +287 -0
  9. rulelearn_ri/algorithms/r2n/simple_rulenet.py +75 -0
  10. rulelearn_ri/algorithms/r2n/training.py +34 -0
  11. rulelearn_ri/algorithms/r2n/utilities.py +117 -0
  12. rulelearn_ri/algorithms/rbm/__init__.py +0 -0
  13. rulelearn_ri/algorithms/rbm/boolean_rule_cg.py +65 -0
  14. rulelearn_ri/algorithms/rbm/rbm/BRCG.py +69 -0
  15. rulelearn_ri/algorithms/rbm/rbm/GLRM.py +98 -0
  16. rulelearn_ri/algorithms/rbm/rbm/__init__.py +6 -0
  17. rulelearn_ri/algorithms/rbm/rbm/beam_search.py +302 -0
  18. rulelearn_ri/algorithms/rbm/rbm/boolean_rule_cg.py +245 -0
  19. rulelearn_ri/algorithms/rbm/rbm/features.py +544 -0
  20. rulelearn_ri/algorithms/rbm/rbm/linear_regression.py +393 -0
  21. rulelearn_ri/algorithms/rbm/rbm/logistic_regression.py +447 -0
  22. rulelearn_ri/algorithms/rbm/utils.py +13 -0
  23. rulelearn_ri/algorithms/ripper/__init__.py +10 -0
  24. rulelearn_ri/algorithms/ripper/base.py +81 -0
  25. rulelearn_ri/algorithms/ripper/binding.py +541 -0
  26. rulelearn_ri/algorithms/ripper/mdl.py +97 -0
  27. rulelearn_ri/algorithms/ripper/pruning.py +212 -0
  28. rulelearn_ri/algorithms/ripper/ripper.py +600 -0
  29. rulelearn_ri/algorithms/ripper/ripper_ruleset_generator.py +26 -0
  30. rulelearn_ri/algorithms/ripper/single_rule.py +425 -0
  31. rulelearn_ri/dise.py +64 -0
  32. rulelearn_ri/trxf/__init__.py +0 -0
  33. rulelearn_ri/trxf/classifier/__init__.py +0 -0
  34. rulelearn_ri/trxf/classifier/ruleset_classifier.py +153 -0
  35. rulelearn_ri/trxf/core/__init__.py +5 -0
  36. rulelearn_ri/trxf/core/boolean_evaluator.py +15 -0
  37. rulelearn_ri/trxf/core/conjunction.py +50 -0
  38. rulelearn_ri/trxf/core/dnf_ruleset.py +64 -0
  39. rulelearn_ri/trxf/core/feature.py +155 -0
  40. rulelearn_ri/trxf/core/predicate.py +98 -0
  41. rulelearn_ri/trxf/core/ruleset_generator.py +25 -0
  42. rulelearn_ri/trxf/core/utils.py +40 -0
  43. rulelearn_ri/trxf/metrics.py +98 -0
  44. rulelearn_ri/trxf/pmml_export/__init__.py +4 -0
  45. rulelearn_ri/trxf/pmml_export/__version__.py +1 -0
  46. rulelearn_ri/trxf/pmml_export/models/__init__.py +24 -0
  47. rulelearn_ri/trxf/pmml_export/models/attribute.py +24 -0
  48. rulelearn_ri/trxf/pmml_export/models/characteristics.py +20 -0
  49. rulelearn_ri/trxf/pmml_export/models/data_dictionary.py +53 -0
  50. rulelearn_ri/trxf/pmml_export/models/mining_schema.py +25 -0
  51. rulelearn_ri/trxf/pmml_export/models/pmml_ruleset_model.py +16 -0
  52. rulelearn_ri/trxf/pmml_export/models/predicate.py +42 -0
  53. rulelearn_ri/trxf/pmml_export/models/rule.py +26 -0
  54. rulelearn_ri/trxf/pmml_export/models/ruleset.py +28 -0
  55. rulelearn_ri/trxf/pmml_export/models/ruleset_model.py +16 -0
  56. rulelearn_ri/trxf/pmml_export/models/scorecard.py +35 -0
  57. rulelearn_ri/trxf/pmml_export/pmml_exporter.py +18 -0
  58. rulelearn_ri/trxf/pmml_export/reader/__init__.py +2 -0
  59. rulelearn_ri/trxf/pmml_export/reader/abstract_reader.py +16 -0
  60. rulelearn_ri/trxf/pmml_export/reader/trxf_reader.py +113 -0
  61. rulelearn_ri/trxf/pmml_export/serializer/__init__.py +2 -0
  62. rulelearn_ri/trxf/pmml_export/serializer/abstract_serializer.py +11 -0
  63. rulelearn_ri/trxf/pmml_export/serializer/nyoka_serializer.py +162 -0
  64. rulelearn_ri/trxf/scorecard/__init__.py +3 -0
  65. rulelearn_ri/trxf/scorecard/bins.py +253 -0
  66. rulelearn_ri/trxf/scorecard/partition.py +71 -0
  67. rulelearn_ri/trxf/scorecard/scorecard.py +78 -0
  68. rulelearn_ripper_interactive-0.2.3.dist-info/METADATA +164 -0
  69. rulelearn_ripper_interactive-0.2.3.dist-info/RECORD +73 -0
  70. rulelearn_ripper_interactive-0.2.3.dist-info/WHEEL +5 -0
  71. rulelearn_ripper_interactive-0.2.3.dist-info/licenses/LICENSE +201 -0
  72. rulelearn_ripper_interactive-0.2.3.dist-info/licenses/NOTICE +11 -0
  73. rulelearn_ripper_interactive-0.2.3.dist-info/top_level.txt +1 -0
@@ -0,0 +1,34 @@
1
+ import torch
2
+
3
+ import rulelearn_ri.algorithms.r2n.utilities as util
4
+
5
+
6
+ def train(dataloader, model, loss_fn, optimizer, temp, min_temp, decay_rate, coef, mv_reg=1e-4, multivariate=False):
7
+ thresholdnet = model[0].LearningLayer
8
+ rulenet = model[1]
9
+ succes_rate, loop_loss = 0, 0
10
+
11
+ for batch, ((X_cat, X_num), y) in enumerate(dataloader):
12
+ x = [X_cat.float(), X_num.float()]
13
+ pred = model(x).T
14
+
15
+ loss = loss_fn(pred, y.float()) + coef * rulenet.get_penalty()
16
+ if multivariate:
17
+ loss += mv_reg * thresholdnet.get_penalty()
18
+
19
+ # Backpropagation
20
+ optimizer.zero_grad()
21
+ loss.backward()
22
+ torch.nn.utils.clip_grad_norm_(model.parameters(), 1)
23
+ optimizer.step()
24
+
25
+ # Calculating metric
26
+ succes_rate += util.binary_acc(pred, y).item()
27
+ loop_loss += loss.item()
28
+ # Cooling schedule
29
+ temp = temp * decay_rate if temp > min_temp else temp
30
+ if multivariate:
31
+ thresholdnet.update_temp(temp)
32
+ rulenet.update_temp(temp)
33
+
34
+ return temp, loop_loss, succes_rate / len(dataloader)
@@ -0,0 +1,117 @@
1
+ from functools import partial
2
+
3
+ import numpy as np
4
+ import sklearn.metrics as metrics
5
+ import torch
6
+
7
+ basic_metrics_binary = dict(
8
+ acc=metrics.accuracy_score,
9
+ bal_acc=metrics.balanced_accuracy_score,
10
+ f1=lambda y_true, y_pred: metrics.f1_score(y_true, y_pred, average="weighted"),
11
+ precision=lambda y_true, y_pred: metrics.precision_score(y_true, y_pred, average="weighted"),
12
+ recall=lambda y_true, y_pred: metrics.recall_score(y_true, y_pred, average="weighted"),
13
+ )
14
+
15
+
16
+ def binary_acc(y_pred, y_test):
17
+ y_pred_tag = torch.round(y_pred)
18
+
19
+ correct_results_sum = (y_pred_tag == y_test).sum().float()
20
+ acc = correct_results_sum / y_test.shape[0]
21
+ acc = torch.round(acc * 100)
22
+
23
+ return acc
24
+
25
+
26
+ def compute_metrics(y_true, y_pred):
27
+ res = dict()
28
+ for metric in basic_metrics_binary:
29
+ res[metric] = basic_metrics_binary[metric](y_true, y_pred)
30
+ return res
31
+
32
+
33
+ def apply_ruleset(ruleset, x):
34
+ """ Apply a ruleset to an input vector
35
+
36
+ :param ruleset: A 2D list conforming to the format of the output of `extract_ruleset()`
37
+ :param x: A list-like object of 0/1 values representing a single input vector
38
+ :return: The truth value of applying ruleset to x
39
+ """
40
+ transform = {1: lambda z: z == 1,
41
+ 0: lambda z: True,
42
+ -1: lambda z: z == 0}
43
+ or_result = False
44
+ for rule in ruleset:
45
+ and_result = True
46
+ for i, t in enumerate([transform[r] for r in rule]):
47
+ and_result &= t(x[i])
48
+ or_result |= and_result
49
+ return or_result
50
+
51
+
52
+ def batch_apply_ruleset(ruleset, xs):
53
+ """ Batch-apply a ruleset to a list of input vectors
54
+
55
+ :param ruleset: A 2D list conforming to the format of the output of `extract_ruleset()`
56
+ :param xs: A (2D) list-like object of input vectors
57
+ :return: A list of truth values corresponding to each input vector in xs
58
+ """
59
+ return list(map(partial(apply_ruleset, ruleset), xs))
60
+
61
+
62
+ def _rchop(s, suffix):
63
+ if suffix and s.endswith(suffix):
64
+ return s[:-len(suffix)]
65
+ return s
66
+
67
+
68
+ def filter_trivial_predicates(set_of_rules, pred_evaluation):
69
+ """
70
+ This function filters the ruleset by evaluating the rules and predicates on a dataset X.
71
+ It returns a ruleset that filters all the always true predicates and removes the rules that contain an always false predicate.
72
+
73
+ @param set_of_rules: 2D binary list representing a ruleset.
74
+ @param pred_evaluation: 2D binary `np.array` representing the evaluation of each predicate on the input data. Equal to the transpose of the binarized data.
75
+ @return: 2D binary list representing a ruleset.
76
+ """
77
+ # Evaluate which of the predicates evaluate to Always true or always False
78
+
79
+ always_true = np.count_nonzero(pred_evaluation, axis=1) / pred_evaluation.shape[1] == 1
80
+ always_false = np.count_nonzero(pred_evaluation, axis=1) / pred_evaluation.shape[1] == 0
81
+ # Remove the predicates that are always True
82
+ set_of_rules = [np.array(i, dtype=int) for i in set_of_rules]
83
+ for i in set_of_rules:
84
+ i[always_true] = 0
85
+ # Select and remove the rules have at least one always False predicate
86
+ always_false_rules = [np.count_nonzero(np.logical_and(rule, always_false)) for rule in set_of_rules]
87
+ set_of_rules = [i for i, j in zip(set_of_rules, always_false_rules) if j == 0]
88
+
89
+ return set_of_rules
90
+
91
+
92
+ def simplify_ruleset(ruleset):
93
+ ruleset = [rule for rule in ruleset if
94
+ np.count_nonzero(rule) != 0] # Remove the ALWAYS FALSE rules in the disjunction.
95
+ simplified_rules = []
96
+ for rule1 in ruleset:
97
+ is_redundant = False
98
+ for rule2 in ruleset:
99
+ if not np.array_equal(rule2, rule1) and _subsumes(rule2, rule1):
100
+ is_redundant = True
101
+ break
102
+ if not is_redundant:
103
+ simplified_rules.append(rule1)
104
+ simplified_rules = _deduplicate(simplified_rules)
105
+
106
+ return simplified_rules
107
+
108
+
109
+ def _deduplicate(simplified_rules):
110
+ tupled_lst = set(map(tuple, simplified_rules))
111
+ simplified_rules = list(map(list, tupled_lst))
112
+ simplified_rules = [np.array(i, dtype=int) for i in simplified_rules]
113
+ return simplified_rules
114
+
115
+
116
+ def _subsumes(rule1, rule2):
117
+ return np.array_equal(np.logical_and(rule1, rule2), rule1)
File without changes
@@ -0,0 +1,65 @@
1
+ from rulelearn_ri.algorithms.rbm.rbm import BooleanRuleCG as brcg
2
+
3
+ from rulelearn_ri.trxf.core.dnf_ruleset import DnfRuleSet, Conjunction
4
+ from rulelearn_ri.trxf.core.predicate import Predicate, Feature
5
+ from .utils import OPERATOR_MAPS
6
+
7
+
8
+ class BooleanRuleCG(brcg):
9
+ """
10
+ Same class as `aix360.algorithms.rbm.boolean_rule_cg.BooleanRuleCG`, the only
11
+ difference being that the explanations are available in the Technical Rule
12
+ Exchange Format (TRXF).
13
+ """
14
+
15
+ def __init__(self, *args, **kwargs):
16
+ super().__init__(*args, **kwargs)
17
+
18
+ def explain(self, maxConj=None, prec=2) -> DnfRuleSet:
19
+ """
20
+ Overriden method that returns the BRCG learnt rules as a TRXF Ruleset.
21
+ """
22
+ # Selected conjunctions
23
+ z = self.z.loc[:, self.w > 0.5]
24
+ truncate = (maxConj is not None) and (z.shape[1] > maxConj)
25
+ nConj = maxConj if truncate else z.shape[1]
26
+
27
+ # Sort conjunctions by increasing order
28
+ idxSort = z.sum().sort_values().index[:nConj]
29
+
30
+ # Iterate over sorted conjunctions
31
+ conj = [] # List of conjunctions
32
+ for i in idxSort:
33
+ pred_list = []
34
+
35
+ # MultiIndex of features participating in rule i
36
+ idxFeat = z.index[z[i] > 0]
37
+
38
+ # String representations of features
39
+ feats = idxFeat.get_level_values(0)
40
+ ops = idxFeat.get_level_values(1)
41
+ values = idxFeat.get_level_values(2).to_series()
42
+
43
+ for f, o, v in zip(feats, ops, values):
44
+
45
+ if o in ['', 'not']:
46
+ if "=" in f:
47
+ # Encoded feature
48
+ f, v = f.split("=")
49
+ else:
50
+ # boolean column
51
+ v = True # force values for boolean columms
52
+
53
+ pred_list.append(Predicate(Feature(f), OPERATOR_MAPS[o], v))
54
+
55
+ c = Conjunction(predicate_list=pred_list)
56
+ conj.append(c)
57
+
58
+ if self.CNF:
59
+ then_part = 0
60
+ else:
61
+ then_part = 1
62
+
63
+ res = DnfRuleSet(conjunctions=conj,then_part=then_part)
64
+
65
+ return res
@@ -0,0 +1,69 @@
1
+ from rulelearn_ri.dise import DISExplainer
2
+
3
+
4
+ class BRCGExplainer(DISExplainer):
5
+ """
6
+ Boolean Rule Column Generation explainer. Provides access to
7
+ :class:`aix360.algorithms.rbm.boolean_rule_cg.BooleanRuleCG`, which
8
+ implements a directly interpretable supervised learning method
9
+ for binary classification that learns a Boolean rule in disjunctive
10
+ normal form (DNF) or conjunctive normal form (CNF) using column generation (CG).
11
+ AIX360 implements a heuristic beam search version of BRCG that is less
12
+ computationally intensive than the published integer programming version [#NeurIPS2018]_.
13
+
14
+ References:
15
+ .. [#NeurIPS2018] `S. Dash, O. Günlük, D. Wei, "Boolean decision rules via
16
+ column generation." Neural Information Processing Systems (NeurIPS), 2018.
17
+ <https://papers.nips.cc/paper/7716-boolean-decision-rules-via-column-generation.pdf>`_
18
+ """
19
+
20
+ def __init__(self, model):
21
+ """
22
+ Initialize a BRCGExplainer object.
23
+
24
+ Args:
25
+ model: model to operate on, instance of :class:`aix360.algorithms.rbm.boolean_rule_cg.BooleanRuleCG`
26
+ """
27
+ super(BRCGExplainer, self).__init__()
28
+ self._model = model
29
+
30
+ def set_params(self, *argv, **kwargs):
31
+ """
32
+ Set parameters for the explainer.
33
+ """
34
+ pass
35
+
36
+ def fit(self, X_train, Y_train, *argv, **kwargs):
37
+ """Fit model to training data.
38
+
39
+ Args:
40
+ X_train (DataFrame): Binarized features with MultiIndex column labels
41
+ Y_train (array): Binary-valued target variable
42
+ Returns:
43
+ BRCGExplainer: Self
44
+ """
45
+ self._model.fit(X_train, Y_train, **kwargs)
46
+
47
+ def predict(self, X, *argv, **kwargs):
48
+ """Predict class labels.
49
+
50
+ Args:
51
+ X (DataFrame): Binarized features with MultiIndex column labels
52
+ Returns:
53
+ array: y -- Predicted labels
54
+ """
55
+ return self._model.predict(X, **kwargs)
56
+
57
+ def explain(self, *argv, **kwargs):
58
+ """Return rules comprising the underlying model.
59
+
60
+ Args:
61
+ maxConj (int, optional): Maximum number of conjunctions to show
62
+ prec (int, optional): Number of decimal places to show for floating-value thresholds
63
+ Returns:
64
+ Dictionary containing
65
+
66
+ * isCNF (bool): flag signaling whether model is CNF or DNF
67
+ * rules (list): selected conjunctions formatted as strings
68
+ """
69
+ return self._model.explain(**kwargs)
@@ -0,0 +1,98 @@
1
+ from rulelearn_ri.dise import DISExplainer
2
+
3
+
4
+ class GLRMExplainer(DISExplainer):
5
+ """
6
+ Generalized Linear Rule Model explainer. Provides access to the following
7
+ directly interpretable supervised learning methods:
8
+
9
+ * **Linear Rule Regression:** linear regression on rule-based features [#Icml2019]_.
10
+ * **Logistic Rule Regression:** logistic regression on rule-based features [#Icml2019]_.
11
+
12
+ References:
13
+ .. [#Icml2019] `D. Wei, S. Dash, T. Gao, O. Günlük, "Generalized linear rule
14
+ models." International Conference on Machine Learning (ICML), 2019.
15
+ <http://proceedings.mlr.press/v97/wei19a/wei19a.pdf>`_
16
+ """
17
+
18
+ def __init__(self, model):
19
+ """
20
+ Initialize a GLRMExplainer object.
21
+
22
+ Args:
23
+ model: model to operate on. Instance of either
24
+
25
+ * :class:`aix360.algorithms.rbm.linear_regression.LinearRuleRegression` or
26
+ * :class:`aix360.algorithms.rbm.logistic_regression.LogisticRuleRegression`
27
+ """
28
+ super(GLRMExplainer, self).__init__()
29
+ self._model = model
30
+
31
+ def set_params(self, *argv, **kwargs):
32
+ """
33
+ Set parameters for the explainer.
34
+ """
35
+ pass
36
+
37
+ def fit(self, X_train, Y_train, Xstd=None):
38
+ """Fit model to training data.
39
+
40
+ Args:
41
+ X_train (DataFrame): Binarized features with MultiIndex column labels
42
+ Y_train (array): Target variable
43
+ Xstd (DataFrame, optional): Standardized numerical features
44
+ Returns:
45
+ GLRMExplainer: Self
46
+ """
47
+ self._model.fit(X_train, Y_train, Xstd)
48
+
49
+ def predict(self, X, Xstd=None):
50
+ """Predict responses.
51
+
52
+ Args:
53
+ X (DataFrame): Binarized features with MultiIndex column labels
54
+ Xstd (DataFrame, optional): Standardized numerical features
55
+ Returns:
56
+ array: y -- Predicted responses
57
+ """
58
+ return self._model.predict(X, Xstd)
59
+
60
+ def predict_proba(self, X, Xstd=None):
61
+ """Predict probabilities of Y=1. Only available if underlying model implements
62
+ `predict_proba` method.
63
+
64
+ Args:
65
+ X (DataFrame): Binarized features with MultiIndex column labels
66
+ Xstd (DataFrame, optional): Standardized numerical features
67
+ Returns:
68
+ array: p -- Predicted probabilities
69
+
70
+ Raises:
71
+ ValueError: if model doesn't implement `predict_proba`
72
+ """
73
+ if hasattr(self._model, 'predict_proba'):
74
+ return self._model.predict_proba(X, Xstd)
75
+ raise ValueError("Current model doesn't predict probabilities")
76
+
77
+ def explain(self, maxCoeffs=None, highDegOnly=False, prec=2):
78
+ """Return DataFrame holding model features and their coefficients.
79
+
80
+ Args:
81
+ maxCoeffs (int, optional): Maximum number of rules/numerical features to show
82
+ highDegOnly (bool, optional): Only show higher-degree rules
83
+ prec (int, optional): Number of decimal places to show for floating-value thresholds
84
+ Returns:
85
+ DataFrame: dfExpl -- Rules/numerical features and their coefficients
86
+ """
87
+ return self._model.explain(maxCoeffs, highDegOnly, prec)
88
+
89
+ def visualize(self, Xorig, fb, features=None):
90
+ """Plot generalized additive model component, which includes first-degree rules
91
+ and linear functions of unbinarized ordinal features but excludes higher-degree rules.
92
+
93
+ Args:
94
+ Xorig (DataFrame): Original unbinarized features
95
+ fb: FeatureBinarizer object used to binarize features
96
+ features (list, optional): Subset of features to be plotted
97
+ """
98
+ return self._model.visualize(Xorig, fb, features)
@@ -0,0 +1,6 @@
1
+ from .features import FeatureBinarizer, FeatureBinarizerFromTrees
2
+ from .linear_regression import LinearRuleRegression
3
+ from .logistic_regression import LogisticRuleRegression
4
+ from .boolean_rule_cg import BooleanRuleCG
5
+ from .GLRM import GLRMExplainer
6
+ from .BRCG import BRCGExplainer