Explain¶
Explainability module: unified API for SHAP, LIME, PDP, interactions, and counterfactuals.
Provides a consistent interface for model explanation methods with automatic method selection based on model type.
Example
>>> import endgame as eg
>>> from endgame.explain import explain, SHAPExplainer, LIMEExplainer
>>>
>>> # One-line explanation with auto-detection
>>> explanation = explain(model, X_test)
>>> explanation.plot(kind='bar')
>>> df = explanation.to_dataframe()
>>>
>>> # Explicit SHAP
>>> shap_exp = SHAPExplainer(model)
>>> explanation = shap_exp.explain(X_test)
>>>
>>> # Explicit LIME (local)
>>> lime_exp = LIMEExplainer(model)
>>> explanation = lime_exp.explain(X_test[:1])
>>>
>>> # Partial dependence
>>> from endgame.explain import PartialDependence
>>> pdp = PartialDependence(model)
>>> explanation = pdp.explain(X_train, features=[0, 1, 2])
>>>
>>> # Feature interactions
>>> from endgame.explain import FeatureInteraction
>>> fi = FeatureInteraction(model)
>>> explanation = fi.explain(X_train)
>>>
>>> # Counterfactuals
>>> from endgame.explain import CounterfactualExplainer
>>> cf = CounterfactualExplainer(model, X_train)
>>> explanation = cf.explain(X_test[:1], desired_class=1)
- endgame.explain.explain(model, X, *, method='auto', feature_names=None, random_state=None, verbose=False, **kwargs)[source]¶
One-line model explanation with automatic method selection.
Selects the most appropriate explanation method based on the model type and data characteristics:
Tree-based models (LightGBM, XGBoost, CatBoost, RandomForest, etc.) ->
SHAPExplainerwithTreeExplainer.Linear models (LogisticRegression, Ridge, Lasso, etc.) ->
SHAPExplainerwithLinearExplainer.Other models with
n_samples <= 500->SHAPExplainerwithKernelExplainer.Other models with
n_samples > 500->SHAPExplainerwithKernelExplainer(subsampled).
- Parameters:
model (sklearn-compatible estimator) – A fitted model.
X (array-like of shape (n_samples, n_features)) – Data to explain.
method (str, default='auto') – Explanation method: -
'auto': Auto-select (see above). -'shap': Force SHAP. -'lime': Force LIME. -'pdp': Partial dependence.random_state (int, optional) – Random seed.
verbose (bool, default=False) – Verbose output.
**kwargs (
Any) – Forwarded to the underlying explainer’sexplain()method.
- Return type:
- Returns:
Explanation – The computed explanation.
Examples
>>> from endgame.explain import explain >>> explanation = explain(model, X_test) >>> explanation.plot(kind='bar') >>> print(explanation.top_features(5)) >>> df = explanation.to_dataframe()
- class endgame.explain.Explanation(values, base_value=None, feature_names=None, method='', metadata=<factory>)[source]¶
Bases:
objectContainer for feature-attribution explanations.
Holds SHAP values, LIME weights, partial dependence grids, or any other per-feature attribution output. Provides convenience methods for plotting and DataFrame export.
- Parameters:
- values¶
Attribution values. Shape depends on the method: - Global:
(n_features,)(mean absolute attributions). - Local:(n_samples, n_features)or(n_features,)for asingle instance.
PDP:
(n_grid_points,)or(n_grid_1, n_grid_2)for 2-D.
- Type:
np.ndarray
- base_value¶
Expected value / base prediction the attributions are relative to.
- Type:
float or np.ndarray or None
Examples
>>> explanation.plot(kind='bar') >>> df = explanation.to_dataframe()
- plot(kind='bar', max_display=20, show=True, **kwargs)[source]¶
Plot the explanation.
- Parameters:
kind (str, default='bar') – Plot type. Supported values depend on the explanation method: -
'bar': Horizontal bar chart of mean |attributions| (all methods). -'beeswarm': SHAP beeswarm summary plot (SHAP only). -'waterfall': Waterfall plot for a single prediction (SHAP only). -'heatmap': SHAP heatmap of sample-level attributions. -'force': SHAP force plot for a single prediction.max_display (int, default=20) – Maximum number of features to display.
show (bool, default=True) – Whether to call
matplotlib.pyplot.show().**kwargs (
Any) – Forwarded to the underlying plotting function.
- Return type:
- Returns:
matplotlib.figure.Figure or None – The figure object when show is False.
- to_dataframe()[source]¶
Convert explanation to a pandas DataFrame.
- Return type:
DataFrame- Returns:
pd.DataFrame – DataFrame with feature names as the index and attribution values as columns.
- Raises:
ImportError – If pandas is not installed.
- class endgame.explain.BaseExplainer(model, feature_names=None, random_state=None, verbose=False)[source]¶
Bases:
ABCAbstract base class for all Endgame explainers.
Subclasses must implement
explain()which returns anExplanationobject.- Parameters:
- abstractmethod explain(X, **kwargs)[source]¶
Generate an explanation for the given data.
- Parameters:
X (array-like of shape (n_samples, n_features)) – Data to explain.
**kwargs (
Any) – Method-specific arguments.
- Return type:
- Returns:
Explanation – The computed explanation.
- class endgame.explain.SHAPExplainer(model, explainer_type='auto', background_samples=100, max_samples=None, check_additivity=False, feature_names=None, random_state=None, verbose=False)[source]¶
Bases:
BaseExplainerSHAP-based explainer with automatic backend selection.
Supports
TreeExplainer,LinearExplainer,DeepExplainer, andKernelExplainer. By default the most efficient backend is chosen automatically based on the model type.- Parameters:
model (sklearn-compatible estimator) – A fitted model.
explainer_type (str, default='auto') – SHAP explainer backend: -
'auto': Auto-detect from model type. -'tree':shap.TreeExplainer(tree-based models). -'linear':shap.LinearExplainer(linear models). -'deep':shap.DeepExplainer(neural networks). -'kernel':shap.KernelExplainer(model-agnostic).background_samples (int, default=100) – Number of background samples for Kernel / Linear / Deep explainers.
max_samples (int, optional) – If set, subsample X to at most this many rows before computing SHAP values (useful for large datasets with KernelExplainer).
check_additivity (bool, default=False) – Whether to verify the SHAP additivity property.
random_state (int, optional) – Random seed.
verbose (bool, default=False) – Verbose output.
Examples
>>> from endgame.explain import SHAPExplainer >>> explainer = SHAPExplainer(model, explainer_type='auto') >>> explanation = explainer.explain(X_test) >>> explanation.plot(kind='beeswarm') >>> print(explanation.top_features(5))
- explain(X, *, check_additivity=None)[source]¶
Compute SHAP values for X.
- Parameters:
X (array-like of shape (n_samples, n_features)) – Data to explain.
check_additivity (bool, optional) – Override the instance-level
check_additivitysetting.
- Return type:
- Returns:
Explanation – An
Explanationcontaining sample-level SHAP values of shape(n_samples, n_features).
- explain_interaction(X)[source]¶
Compute SHAP interaction values (tree models only).
- Parameters:
X (array-like of shape (n_samples, n_features)) – Data to explain.
- Return type:
- Returns:
Explanation – An
Explanationwithvaluesof shape(n_samples, n_features, n_features).- Raises:
ValueError – If the model is not tree-based.
- class endgame.explain.LIMEExplainer(model, mode='auto', num_features=10, num_samples=5000, kernel_width=None, discretize_continuous=True, feature_names=None, random_state=None, verbose=False)[source]¶
Bases:
BaseExplainerLIME (Local Interpretable Model-agnostic Explanations) wrapper.
Generates local explanations by fitting an interpretable model in the neighbourhood of each instance.
- Parameters:
model (sklearn-compatible estimator) – A fitted model with
predict(regression) orpredict_proba(classification).mode (str, default='auto') –
Explanation mode: -
'auto': Infer from the model (usespredict_probawhenavailable).
'classification': Force classification mode.'regression': Force regression mode.
num_features (int, default=10) – Maximum number of features in each local explanation.
num_samples (int, default=5000) – Size of the neighbourhood sample used by LIME.
kernel_width (float, optional) – Width of the exponential kernel. If
None, LIME uses its default (sqrt(n_features) * 0.75).discretize_continuous (bool, default=True) – Whether to discretize continuous features (LIME default).
random_state (int, optional) – Random seed.
verbose (bool, default=False) – Verbose output.
Examples
>>> from endgame.explain import LIMEExplainer >>> explainer = LIMEExplainer(model, mode='classification') >>> explanation = explainer.explain(X_test[:10]) >>> explanation.plot(kind='bar')
- explain(X, *, labels=None, top_labels=None)[source]¶
Generate LIME explanations for the rows of X.
When X has a single row, the explanation values have shape
(n_features,). For multiple rows, the values have shape(n_samples, n_features)where each row is the local weight vector for that instance.- Parameters:
X (array-like of shape (n_samples, n_features)) – Instances to explain.
labels (tuple of int, optional) – Class labels to explain (classification only). Defaults to the predicted class.
top_labels (int, optional) – Number of top predicted classes to explain.
- Return type:
- Returns:
Explanation – An
Explanationwith local attribution values.
- class endgame.explain.PartialDependence(model, grid_resolution=50, percentiles=(0.05, 0.95), kind='average', feature_names=None, random_state=None, verbose=False)[source]¶
Bases:
BaseExplainerPartial Dependence computation for 1-D and 2-D feature effects.
Uses
sklearn.inspection.partial_dependence()when available, with a brute-force fallback for models that do not expose thepredictcontract sklearn expects.- Parameters:
model (sklearn-compatible estimator) – A fitted model with
predict(regression) orpredict_proba(classification).grid_resolution (int, default=50) – Number of evenly-spaced grid points along each feature axis.
percentiles (tuple of float, default=(0.05, 0.95)) – Lower and upper percentile bounds of the grid.
kind (str, default='average') –
'average'for the marginal expectation (classic PDP), or'individual'for Individual Conditional Expectation (ICE).random_state (int, optional) – Random seed.
verbose (bool, default=False) – Verbose output.
Examples
>>> pdp = PartialDependence(model) >>> # 1-D partial dependence for feature 0 >>> exp1d = pdp.explain(X_train, features=[0]) >>> exp1d.plot() >>> >>> # 2-D partial dependence for feature pair (0, 1) >>> exp2d = pdp.explain(X_train, features=[(0, 1)]) >>> exp2d.plot()
- explain(X, *, features=None, target_class=None)[source]¶
Compute partial dependence for the requested features.
- Parameters:
X (array-like of shape (n_samples, n_features)) – Data used to marginalise over.
features (list of int or list of (int, int), optional) – Feature indices to compute PDP for. Each element is either a single int (1-D PDP) or a pair of ints (2-D PDP). If
None, computes 1-D PDP for all features.target_class (int, optional) – For classifiers, the index of the class to explain. Defaults to class 1 for binary classification.
- Return type:
- Returns:
Explanation – An
Explanationwhosevaluesandmetadatacontain PDP grids for each requested feature (set).
- plot_feature(explanation, feature, *, ax=None, show=True, **kwargs)[source]¶
Plot partial dependence for a single feature (or pair).
- Parameters:
explanation (Explanation) – Result from
explain().feature (int or (int, int)) – Feature index (or pair for 2-D).
ax (matplotlib.axes.Axes, optional) – Axes to plot on. If
None, a new figure is created.show (bool, default=True) – Whether to call
plt.show().**kwargs (
Any) – Forwarded to matplotlib plotting functions.
- Return type:
- Returns:
matplotlib.figure.Figure
- class endgame.explain.FeatureInteraction(model, grid_resolution=25, percentiles=(0.05, 0.95), feature_names=None, random_state=None, verbose=False)[source]¶
Bases:
BaseExplainerFeature interaction strength via the H-statistic.
The H-statistic measures the proportion of variance in the joint partial dependence that cannot be explained by the sum of the individual partial dependences. A value of 0 means no interaction; values near 1 indicate strong interaction.
- Parameters:
model (sklearn-compatible estimator) – A fitted model.
grid_resolution (int, default=25) – Number of grid points per feature for PDP estimation. Kept lower than PDP defaults for speed since we evaluate many pairs.
percentiles (tuple of float, default=(0.05, 0.95)) – Feature range bounds.
random_state (int, optional) – Random seed.
verbose (bool, default=False) – Verbose output.
Examples
>>> fi = FeatureInteraction(model) >>> explanation = fi.explain(X_train, features=[(0, 1), (2, 3)]) >>> explanation.to_dataframe()
- explain(X, *, features=None, top_k=10)[source]¶
Compute pairwise H-statistics.
- Parameters:
X (array-like of shape (n_samples, n_features)) – Data used for PDP computation.
features (list of (int, int), optional) – Feature pairs to evaluate. If
None, evaluates thetop_kmost important features (by variance of 1-D PDP) crossed with each other.top_k (int, default=10) – When features is
None, use the top-k features to form pairs.
- Return type:
- Returns:
Explanation – An
Explanationwith H-statistic values and metadata containing per-pair results.
- plot_interaction_matrix(explanation, *, ax=None, show=True, **kwargs)[source]¶
Plot the pairwise interaction matrix as a heatmap.
- Parameters:
explanation (Explanation) – Result from
explain().ax (matplotlib.axes.Axes, optional) – Axes to plot on.
show (bool, default=True) – Whether to call
plt.show().**kwargs (
Any) – Forwarded tomatplotlib.pyplot.imshow.
- Return type:
- Returns:
matplotlib.figure.Figure
- class endgame.explain.CounterfactualExplainer(model, training_data, continuous_features=None, outcome_name='outcome', feature_names=None, random_state=None, verbose=False)[source]¶
Bases:
BaseExplainerCounterfactual explanation generator using DiCE.
Finds diverse sets of minimal feature perturbations that change the model’s prediction to a desired outcome.
- Parameters:
model (sklearn-compatible estimator) – A fitted classifier or regressor.
training_data (array-like or pd.DataFrame) – Training data used to define feature ranges and constraints.
continuous_features (list of str, optional) – Names of continuous features. If
None, all features are assumed continuous.outcome_name (str, default='outcome') – Name of the target column (used internally by DiCE).
random_state (int, optional) – Random seed.
verbose (bool, default=False) – Verbose output.
Examples
>>> cf = CounterfactualExplainer(model, X_train) >>> explanation = cf.explain(X_test[:1], desired_class=1, n_counterfactuals=3) >>> print(explanation.metadata['counterfactuals'])
- explain(X, *, desired_class='opposite', n_counterfactuals=3, method='random', features_to_vary=None, permitted_range=None)[source]¶
Generate counterfactual explanations.
- Parameters:
X (array-like of shape (n_instances, n_features)) – Instance(s) to explain. Typically a single row.
desired_class (int or str, default='opposite') – Target class for the counterfactual.
'opposite'flips a binary prediction.n_counterfactuals (int, default=3) – Number of diverse counterfactuals to generate per instance.
method (str, default='random') – DiCE generation method: -
'random': Random perturbation search. -'genetic': Genetic algorithm search. -'kdtree': KD-tree nearest-neighbour search.features_to_vary (list of str, optional) – Restrict changes to these features only. If
None, all features may be varied.permitted_range (dict, optional) – Per-feature permitted ranges, e.g.
{'age': [18, 65], 'income': [0, 200000]}.
- Return type:
- Returns:
Explanation – An
Explanationwith: -values: Mean absolute change across counterfactuals(feature-level importance of change).
metadata['counterfactuals']: DataFrame of generated counterfactuals.metadata['original']: The original instance(s).