teex.decisionRule package#

teex.decisionRule.data module#

Module for synthetic and real datasets with available ground truth decision rule explanations. Also contains methods and classes for decisionRule data manipulation.

All of the datasets must be instanced first. Then, when sliced, they all return the observations, labels and ground truth explanations, respectively.

class teex.decisionRule.data.DecisionRule(statements=None, result=None)[source]#

Bases: object

A conjunction of statements as conditions that imply a result. Internally, the rule is represented as a dictionary of Statement with the feature names as unique identifiers. A feature cannot have more than one Statement (Statements can be binary). This class is capable of adapting previous Statement objects depending on new Statements that are added to it with the upsert method (see upsert_statement() method).

Example:

>>> c1 = Statement('a',lowB=2,upperB=3)     # 2 < a < 3
>>> r = DecisionRule([c1])
>>> # update the bounds for the feature 'a'
>>> c2 = Statement('a',lowB=3,upperB=5)
>>> r.upsert_statement(c2,updateOperators=False)
>>> # we can also insert new statements via upsert or insert
>>> c3 = Statement('b',lowOp='<=',lowB=3,upperOp='<',upperB=6)
>>> r.upsert_statement(c3)
>>> # a Statement cannot be updated if one of them is different class as the other (binary / unary):
>>> c4 = Statement('b', 3, op='>')
>>> r.upsert_statement(c4) # THIS WILL RAISE AN ERROR!
Parameters:
  • statements – (list-like of Statement objects) Statements as conditions that make the result be True.

  • result (Statement) – Logical implication of the Decision Rule when all of the Statements are True.

delete_statement(feature) None[source]#

Deletes a Statement in the rule.

Parameters:

feature (str) – name of the feature in the Statement to be deleted.

get_features() list[source]#

Gets features in the Rule.

Return list:

feature names as identifiers of the Statements in the rule.

insert_statement(statement: Statement) None[source]#

Add Statement inplace to the conjunction.

Parameters:

statement – Statement object

rename_statement(oldFeature, newFeature) None[source]#

Changes the identifier of a Statement.

Parameters:
  • oldFeature (str) – id of the Statement to rename.

  • newFeature (str) – new id of the Statement.

replace_statement(oldFeature, newStatement: Statement) None[source]#

Replaces a Statement with another.

Parameters:
  • oldFeature (str) – identifier of the Statement to replace.

  • newStatement (Statement) – new statement.

set_result(result) None[source]#

Sets the result for the Decision Rule.

Parameters:

result (Statement) – statement as logical implication.

upsert_statement(statement: Statement, updateOperators: bool = True) None[source]#

If a statement already exists within the rule, updates its bounds (replacing or defining them) and its operators if specified. If not, inserts the statement as a new condition. If an existing condition is of different type (binary / non-binary) as the new condition, the update fails. A bound update is only performed if the new bound/s != np.inf or -np.inf.

Parameters:
  • statement – Statement object to upsert

  • updateOperators – Should the operators be updated too?

class teex.decisionRule.data.SenecaDR(nSamples: int = 1000, nFeatures: int = 3, featureNames=None, randomState: int = 888)[source]#

Bases: _SyntheticDataset

Generate synthetic binary classification data with ground truth decision rule explanations. The returned decision rule g.t. explanations are instances of the DecisionRule class.

Ground truth explanations are generated with the TransparentRuleClassifier class. The method was presented in [Evaluating local explanation methods on ground truth, Riccardo Guidotti, 2021]. From this class one can also obtain a trained transparent model (instance of TransparentRuleClassifier).

When sliced, this object will return
  • X (ndarray) of shape (nSamples, nFeatures) or (nFeatures). Generated data.

  • y (ndarray) of shape (nSamples,) or int. Binary data labels.

  • explanations (list) of DecisionRule objects of length (nSamples) or DecisionRule object. Generated ground truth explanations.

Parameters:
  • nSamples (int) – number of samples to be generated.

  • nFeatures (int) – total number of features in the generated data.

  • featureNames – (array-like) names of the generated features. If not provided, a list with the generated feature names will be returned by the function (necessary because the g.t. decision rules use them).

  • randomState (int) – random state seed.

class teex.decisionRule.data.Statement(feature, val=inf, op='=', lowOp=None, lowB=- inf, upperOp=None, upperB=inf)[source]#

Bases: object

Class representing the atomic structure of a rule. A Statement follows the structure of ‘feature’ <operator> ‘value’. It can also be binary, like so: value1 <lowOp> feature <upperOp> value2. Valid operators are {‘=’, ‘!=’, ‘>’, ‘<’, ‘>=’, ‘<=’} or {‘<’, ‘<=’} in the case of a binary statement. The class will store upper and lower bound values if the lower and upper operators are specified (both, just 1 is not valid). If the upper and lower operators are not specified, a unary Statement will be created.

Although unary Statements (except ‘!=’) have translation into single binary Statements, they are separately represented for clarity. Moreover, unary Statements with operators ‘=’ and ‘!=’ are able to represent non-numeric values.

Example:

>>> Statement('a',1.5)                                     # a = 1.5
>>> Statement('a',1.5,op='!=')                             # a != 1.5
>>> Statement('a',lowOp='<',lowB=2,upperOp='<',upperB=5)   # 2 < a < 5
>>> Statement('a',lowOp='<',lowB=2)                        # 2 < a Wrong. Need to explicitly specify upper op
>>> Statement('a',lowOp='<',lowB=2,upperOp='<')            # 2 < a < np.inf
Parameters:
  • feature (str) – name of the feature for the Statement

  • val – (float or str) Value for the statement (if not binary). Default np.inf.

  • op (str) – Operator for the statement (if not binary)

  • lowOp (str) – Operator for the lower bound (if binary)

  • lowB (float) – Value of the upper bound (if binary). Default -np.inf.

  • upperOp (str) – Operator for the upper bound (if binary)

  • upperB (float) – Value of the lower bound (if binary). Default np.inf.

class teex.decisionRule.data.TransparentRuleClassifier(**kwargs)[source]#

Bases: _BaseClassifier

Used on the higher level data generation class teex.featureImportance.data.SenecaFI (use that and get it from there preferably).

Transparent, rule-based classifier with decision rules as explanations. For each prediction, the associated ground truth explanation is available with the explain() method. Follows the sklearn API. Presented in [Evaluating local explanation methods on ground truth, Riccardo Guidotti, 2021].

explain(obs)[source]#

Explain observations’ predictions with decision rules.

Parameters:

obs – array of n observations with m features and shape (n, m)

Returns:

list with n DecisionRule objects

fit(data, target, featureNames=None)[source]#

Fits the classifier and automatically parses the learned tree structure into statements.

Parameters:
  • data – (array-like) of shape (n_samples, n_features) The training input samples. Internally, it will be converted to dtype=np.float32.

  • target – (array-like of shape (n_samples,) or (n_samples, n_outputs)) The target values (class labels) as integers or strings.

  • featureNames – (array-like) names of the features in the data. If not specified, they will be created. Stored in self.featureNames.

predict(obs)[source]#

Predicts the class for each observation.

Parameters:

obs – (array-like) of n observations with m features and shape (n, m)

Return np.ndarray:

array of n predicted labels

predict_proba(obs)[source]#

Predicts probability that each observation belongs to each of the c classes.

Parameters:

obs – array of n observations with m features and shape (n, m)

Return np.ndarray:

array of n probability tuples of length c

teex.decisionRule.data.clean_binary_statement(bounds: list)[source]#

Parses binary statement edge cases from a list of operators and values. Checks if the edge cases occur for any pair of operator and value. Does not fix errors with bounds != or =.

f > 3 & f > 4 TRANSFORMS INTO f > 4 f > 3 & f >= 4 TRANSFORMS INTO f >= 4

f < 3 & f < 4 TRANSFORMS INTO f < 3 f <= 3 & f < 4 TRANSFORMS INTO f <= 3

Parameters:

bounds (list) – list with bounds i.e. [(op, val), …, (op, val)]

Returns:

op1, val1, op2, val2

teex.decisionRule.data.rule_to_feature_importance(rules, allFeatures) ndarray[source]#

Converts one or more DecisionRule objects to feature importance vector/s. For each feature in allFeatures, the feature importance representation contains a 1 if there is a :class:’Statement’ with that particular feature in the decision rule and 0 otherwise.

Parameters:
  • rules – (DecisionRule or (1, r) array-like of DecisionRule) Rule/s to convert to feature importance vectors.

  • allFeatures – (array-like of str) List with m features (same as the rule features) whose order the returned array will follow. The features must match the ones used in the decision rules.

Returns:

(binary ndarray of shape (n_features,) or shape (n_rules, n_features)).

teex.decisionRule.data.rulefit_to_decision_rule(rules, minImportance: float = 0.0, minSupport: float = 0.0) Tuple[List[DecisionRule], list][source]#

Transforms rules computed with the RuleFit algorithm (only from this implementation) into DecisionRule objects.

Example:

>>> import pandas as pd
>>> from rulefit import RuleFit
>>>
>>> boston_data = pd.read_csv('https://raw.githubusercontent.com/selva86/datasets/master/BostonHousing.csv')
>>> y = boston_data.medv.values
>>> features = boston_data.columns
>>> X = boston_data.drop("medv", axis=1).values
>>>
>>> rf = RuleFit()
>>> rf.fit(X, y, feature_names=features)
>>>
>>> dRules, _ = rulefit_to_decision_rule(rf.get_rules(), rf.predict(X))
Parameters:
  • rules (pd.DataFrame) – rules computed with the .get_rules() method of RuleFit. Default 0.

  • minImportance (float) – minimum importance for a rule to have to be transformed. Default 0.

  • minSupport (float) – minimum support for a rule to have to be transformed.

Returns:

  • (list) parsed DecisionRules

  • (list) indexes of skipped rows (because of exceptions such as ‘home < 1 & home > 3’).

teex.decisionRule.data.str_to_decision_rule(strRule: str, ruleType: str = 'binary') DecisionRule[source]#

Converts a string representing a rule into a DecisionRule object. The string must contain the individual feature bounds separated by ‘&’. For each feature bound, the feature must appear first. If ruleType='binary', it is not necessary to explicitly specify both bounds: the missing one will be induced. To imply a result, use ‘->’ and follow it with a statement representation. This method is robust to situations like feature > 3 & feature > 4 and missing whitespaces.

Example:

>>> r = 'a != 2.5 -> res > 3'
>>> print(str_to_decision_rule(r,'unary'))
>>> r = 'a <= 2.5 & a > 1 -> res > 3'
>>> print(str_to_decision_rule(r,'binary'))
>>> r = 'a <= 2.5 & a > 1 & b > 1 -> res > 3 & res <= 5'
>>> print(str_to_decision_rule(r,'binary'))
>>> r = 'a <= 2.5 & a > 1 & b > 1 -> res = class0'
>>> print(str_to_decision_rule(r,'binary'))
>>> print(str_to_decision_rule('d > 1 & d > 3 & d >= 4 & c < 4 & c < 3 & c <= 2-> home > 1 & home < 3')) # is robust
Parameters:
  • strRule (str) – string to convert to rule.

  • ruleType (str) – type of the Statement objects contained within the generated DecisionRule object.

teex.decisionRule.eval module#

Module for evaluation of decision rule explanations.

teex.decisionRule.eval.complete_rule_quality(gts: DecisionRule, rules: DecisionRule, eps: float = 0.1) float[source]#

Computes the complete rule quality (crq) between two decision rules. All ‘Statements’ in both rules must be binary (have upper and lower bounds). The metric is defined as the proportion of lower and upper bounds in a rule explanation that are eps-close to the respective lower and upper bounds (same feature) in the ground truth rule explanation amongst those that are \(\neq \infty\). Mathematically, given two rules \(e, \tilde{e}\) and a similarity threshold \(\varepsilon\), the quality of \(e\) with respect to \(\tilde{e}\) is:

\[q(e, \tilde{e}) = \frac{1}{N_{\not\infty}} \sum_{i=1}^{|e|}{\delta_{\varepsilon}(e_i, \tilde e_i)},\]

where

\[\delta_{\varepsilon}(e_i, \tilde{e}_i) = \begin{cases} 1 & \text{if } |e_i - \tilde{e}_i| \leq \varepsilon \wedge |e_i| \neq \infty \wedge |\tilde{e}_i| \neq \infty, \newline 0 & \text{otherwise} \end{cases}\]

Where \(N_{\not \infty}\) is the number of lower and upper bounds that are different from \(\infty\) in both \(e\) and \(\tilde e\). More about this metric can be found in [Evaluating local explanation methods on ground truth, Riccardo Guidotti, 2021].

Example:

>>> c1 = Statement('a',lowB=2,upperB=1)
>>> c2 = Statement('a',lowB=2.2,upperB=1.1)
>>> r1 = DecisionRule([c1])
>>> r2 = DecisionRule([c2])  # both rules contain the feature 'a'
>>> print(complete_rule_quality(r1, r2, eps=0.01))
>>> print(complete_rule_quality(r1, r2, eps=0.1))
>>> print(complete_rule_quality(r1, r2, eps=0.2))
>>> c3 = Statement('b',lowB=2.2,upperB=1.1)
>>> r3 = DecisionRule([c3])
>>> print(complete_rule_quality(r1, r3, eps=0.2))
>>> # The metric does not take the absence of a feature into account
>>> r3 = DecisionRule([c3, c2])
>>> print(complete_rule_quality(r1, r3, eps=0.2))
Parameters:
  • gts – (DecisionRule or array-like of DecisionRules) ground truth rule w.r.t. which to compute the quality

  • rules – (DecisionRule or array-like of DecisionRules) rule to compute the quality for

  • eps – (float) threshold \(\varepsilon\) for the bounds to be taken into account in the metric, with precision up to 3 decimal places.

Returns:

(float or ndarray of shape (n_samples,)) Complete rule quality.

teex.decisionRule.eval.rule_scores(gts: DecisionRule, rules: DecisionRule, allFeatures, metrics=None, average=True, crqParams=None) float[source]#

Quality metrics for teex.decisionRule.data.DecisionRule objects.

Parameters:
  • gts – (DecisionRule or array-like of DecisionRules) ground truth decision rule/s.

  • rules – (DecisionRule or array-like of DecisionRules) approximated decision rule/s.

  • allFeatures – (array-like) names of all of the relevant features (i.e. featureNames of teex.decisionRule.data.SenecaDR object.)

  • metrics

    (array-like of str, default ['fscore']) metrics to compute. Available:

    • ’fscore’: Computes the F1 Score between the ground truths and the predicted vectors.

    • ’prec’: Computes the Precision Score between the ground truths and the predicted vectors.

    • ’rec’: Computes the Recall Score between the ground truths and the predicted vectors.

    • ’crq’: Computes the Complete Rule Quality of rule w.r.t. gt.

    • ’auc’: Computes the ROC AUC Score between the two sets of decision rules.

    • ’cs’: Computes the Cosine Similarity between the two sets of decision rules.

    Note that for ‘fscore’, ‘prec’, ‘rec’, ‘auc’ and ‘cs’ the rules are transformed to binary vectors where there is one entry per possible feature and that entry contains a 1 if the feature is present in the rule, otherwise 0.

  • average – (bool, default True) Used only if gts and rule are array-like. Should the computed metrics be averaged across all of the samples?

  • crqParams (dict) – Extra parameters complete rule quality.

Returns:

(ndarray) specified metric/s in the original order. Can be of shape

  • (n_metrics,) if only one DecisionRule has been provided in both gts and rules or when both are array-like and average=True.

  • (n_metrics, n_samples) if gts and rules are array-like and average=False.