Class ExplainerRF (extends Explainer)
The Random Forest explainer.
This class adapts the generic Explainer to a RandomForest model. It provides methods to:
- set an instance and derive its Boolean (literal-based) representation,
- compute different families of explanations (direct, contrastive, sufficient, majoritary),
- optionally rectify (modify) the random forest to enforce a desired label under given conditions.
Some functions come from the parent class Explainer, their documentation is available in the dedicated page:
- Main Methods:
set_instance,set_features_type,get_model,predict,activate_theory,deactivate_theory,set_excluded_features,unset_excluded_features; - Human-Readable Explanation Methods:
to_features,get_feature_names,get_feature_names_from_literal,reason_contains_features; - Explanation verification methods:
is_implicant,is_reason,is_sufficient_reason,is_contrastive_reason.
Some methods are limited to binary classification (2 classes). When multi-class support
is not available, an exceptionNotImplementedErroris raised.
def __init__(self, random_forest, instance=None): Highlight
Initialize an explainer for a Random Forest model.
Parameters
random_forest : RandomForest
The RandomForest model to explain.
instance : list[int] (optional, default: None)
The instance (observation) for which explanations will be computed.
If None, you must call set_instance before requesting explanations.
def rectify(self, *, conditions, label, tests=False): Highlight
Rectify the random forest to satisfy a labeled constraint.
Rectification enforces that the (parsed) conditions imply the given label in the model, then simplifies the resulting tree (optionally leveraging the explainer’s theory constraints).
Parameters
conditions : list[int]
Conditions (premises part of the classification rule) in the form of a binary representation (list of literals).
label : int
Label representing the conclusion part of the classification rule.
tests : bool (optional, default: False)
If True, runs additional post-steps checks (can be expensive) to ensure rectification
preserved the intended implicant property.
Methods for Calculating Explanations
def direct_reason(self): Highlight
Compute the direct reason for the current instance.
The direct reason corresponds to a subset of the binary representation obtained by collecting the root-to-leaf path conditions (in binary/literal form) that cover the instance across the forest. If the result contains excluded features, None is returned.
Returns
list[int] :
A list of literals representing the direct reason.
None :
If excluded features appear in the direct reason.
def majoritary_reason(self, *, n=1, n_iterations=50, time_limit=None, seed=0): Highlight
Compute a majoritary reason for the current instance.
Informally, a majoritary reason is a subset of the binary representation that covers a majoritary of trees. Returns n majoritary reasons sorted by increasing of the size for the current instance in a Tuple (when n is set to 1, does not return a Tuple but just the reason). Supports excluded features.
Parameters
n : int | Explaining.ALL, (optional, default=1)
Maximum number of majoritary reasons to enumerate. If Explaining.ALL, treated as unbounded.
n_iterations : int (optional, default: 50)
Number of randomized iterations used to extract the smallest one.
time_limit : float, (optional, default: None)
Time limit (seconds) for the whole enumeration. If reached, property elapsed_time is set
to Explaining.TIMEOUT.
seed : int, (optional, default=0) (default: value)
The seed when the greedy algorithm is used. Set to 0 this parameter to use a random seed. The default value is 0.
n_iterations : int, (optional, default: 50)
Only used if n=1. It is the number of iterations done by the greedy algorithm.
Returns
tuple[int] :
if n == 1, returns a single reason as a tuple of literals.
tuple[tuple[int]] :
If n > 1, returns a tuple of reasons (each one is a tuple of literals).
None :
If all reasons contain excluded features.
Raises
ValueError
NotImplementedError
- When n=1, a greedy algorithm (in polynomial time) is called to extract a majoritary reason. n_iterations allows to call the
olgorithm several time to extract the smallest of those calculated.
- When n > 1, a different algorithm is called.
def minimal_contrastive_reason(self, *, n=1, time_limit=None): Highlight
Compute up to n contrastive reasons for the current instance.
Contrastive explanations explain why the instance has not been classified by the ML model as expected.
Parameters
n : int | Explaining.ALL (optional, default=1)
Maximum number of contrastive reasons to return. If a Explaining.ALL is provided, all computed candidates are formatted/returned.
time_limit : float (optional, default=None)
Time limit (seconds) for the whole enumeration. If reached, elapsed_time is set to Explaining.TIMEOUT.
Returns
tuple[int] :
if n == 1, returns a single reason as a tuple of literals.
tuple[tuple[int]] :
If n > 1, returns a tuple of reasons (each one is a tuple of literals).
None :
If all reasons contain excluded features.
def minimal_majoritary_reason(self, *, n=1, time_limit=None): Highlight
Compute up to n minimal majoritary reasons of minimal size.
Returns up n minimal majoritary reason of the current instance in a Tuple (when n is set to 1, does not return a Tuple but just the reason). Supports the excluded features.
Parameters
n : int | Explaining.ALL, (optional, default=1)
Maximum number of majoritary reasons to enumerate. If Explaining.ALL, treated as unbounded.
time_limit : float (optional, default=None)
Time limit (seconds) for the whole enumeration. If reached, elapsed_time is set
to Explaining.TIMEOUT.
Returns
tuple[int] :
if n == 1, returns a single reason as a tuple of literals.
tuple[tuple[int]] :
If n > 1, returns a tuple of reasons (each one is a tuple of literals).
None :
If all reasons contain excluded features.
def minimal_sufficient_reason(self, time_limit=None): Highlight
Compute a minimal-size sufficient reason for the current instance.
This is an optimization variantsufficient_reason that aims to minimize the number of literals in the returned sufficient reason.
Parameters
time_limit : float | None (optional)
Time limit (seconds) for the whole enumeration. If reached, property elapsed_time is set
to Explaining.TIMEOUT.
Returns
list[int] :
A minimal sufficient reason.
None : None
if time limit is reached or if excluded features are necessary).
Computing a minimal sufficient reason is computationally very hard. Thus, it is possible only for small dataset.
def preferred_majoritary_reason(self, *, method, n=1, time_limit=None, weights=None, features_partition=None): Highlight
Compute sufficient reasons optimized by a preference criterion.
This approach consists in exploiting a model, making precise her / his preferences about reasons, to derive only preferred reasons. See the On Preferred Abductive Explanations for Decision Trees and Random Forests paper (Gilles Audemard, Steve Bellart, Louenas Bounia, Frederic Koriche, Jean-Marie Lagniez and Pierre Marquis) for more details.
Parameters
method : PreferredReasonMethod | str
The preference method used to discriminate reasons.
Possible values are defined in the PreferredReasonMethod enum.
n : int | Explaining.ALL (optional, default=1)
Maximum number of majoritary reasons to enumerate. If Explaining.ALL, treated as unbounded.
time_limit : float (optional, default=None)
Time limit (seconds) for the whole enumeration. If reached, property elapsed_time is set
to Explaining.TIMEOUT.
weights : list[float] (optional, default=None)
Per-feature weights.
If None, weights are computed from using the parameter method.
features_partition : object (optional, default=None)
Partitioning information passed to the weight computation helper.
def sufficient_reason(self, *, time_limit=None): Highlight
Compute a sufficient reason.
A sufficient reason is a (typically) minimal subset of the binary representation that still entails the current prediction.
Parameters
time_limit : float | None (optional)
Time limit (seconds) for the whole enumeration. If reached, property elapsed_time is set to Explaining.TIMEOUT.
Explanation Verification Methods
def is_majoritary_reason(self, reason, n_samples=50): Highlight
Heuristically check whether a given reason behaves like a majoritary reason.
The check proceeds in two steps: 1) Verify that reason is an implicant (optionally extended with theory). 2) Randomly try removing literals and test if the reduced set remains an implicant (to detect non-minimality). Only up to n_samples removal attempts are made.