Files
2026-07-13 13:22:52 +08:00

166 lines
4.2 KiB
Python

import numpy as np
import sklearn
from .. import (
DeepExplainer,
GradientExplainer,
KernelExplainer,
LinearExplainer,
SamplingExplainer,
TreeExplainer,
kmeans,
)
from ..explainers import other
from .models import KerasWrap
def linear_shap_corr(model, data):
"""Linear SHAP (corr 1000)"""
return LinearExplainer(model, data, feature_perturbation="correlation_dependent", nsamples=1000).shap_values
def linear_shap_ind(model, data):
"""Linear SHAP (ind)"""
return LinearExplainer(model, data, feature_perturbation="interventional").shap_values
def coef(model, data):
"""Coefficients"""
return other.CoefficentExplainer(model).attributions
def random(model, data):
"""Random
color = #777777
linestyle = solid
"""
return other.RandomExplainer().attributions
def kernel_shap_1000_meanref(model, data):
"""Kernel SHAP 1000 mean ref.
color = red_blue_circle(0.5)
linestyle = solid
"""
return lambda X: KernelExplainer(model.predict, kmeans(data, 1)).shap_values(X, nsamples=1000, l1_reg=0)
def sampling_shap_1000(model, data):
"""IME 1000
color = red_blue_circle(0.5)
linestyle = dashed
"""
return lambda X: SamplingExplainer(model.predict, data).shap_values(X, nsamples=1000)
def tree_shap_tree_path_dependent(model, data):
"""TreeExplainer
color = red_blue_circle(0)
linestyle = solid
"""
return TreeExplainer(model, feature_perturbation="tree_path_dependent").shap_values
def tree_shap_independent_200(model, data):
"""TreeExplainer (independent)
color = red_blue_circle(0)
linestyle = dashed
"""
data_subsample = sklearn.utils.resample(data, replace=False, n_samples=min(200, data.shape[0]), random_state=0)
return TreeExplainer(model, data_subsample, feature_perturbation="interventional").shap_values
def mean_abs_tree_shap(model, data):
"""mean(|TreeExplainer|)
color = red_blue_circle(0.25)
linestyle = solid
"""
def f(X):
v = TreeExplainer(model).shap_values(X)
if isinstance(v, list):
return [np.tile(np.abs(sv).mean(0), (X.shape[0], 1)) for sv in v]
else:
return np.tile(np.abs(v).mean(0), (X.shape[0], 1))
return f
def saabas(model, data):
"""Saabas
color = red_blue_circle(0)
linestyle = dotted
"""
return lambda X: TreeExplainer(model).shap_values(X, approximate=True)
def tree_gain(model, data):
"""Gain/Gini Importance
color = red_blue_circle(0.25)
linestyle = dotted
"""
return other.TreeGainExplainer(model).attributions
def lime_tabular_regression_1000(model, data):
"""LIME Tabular 1000
color = red_blue_circle(0.75)
"""
return lambda X: other.LimeTabularExplainer(model.predict, data, mode="regression").attributions(X, nsamples=1000)
def lime_tabular_classification_1000(model, data):
"""LIME Tabular 1000
color = red_blue_circle(0.75)
"""
return lambda X: other.LimeTabularExplainer(model.predict_proba, data, mode="classification").attributions(
X, nsamples=1000
)[1]
def maple(model, data):
"""MAPLE
color = red_blue_circle(0.6)
"""
return lambda X: other.MapleExplainer(model.predict, data).attributions(X, multiply_by_input=False)
def tree_maple(model, data):
"""Tree MAPLE
color = red_blue_circle(0.6)
linestyle = dashed
"""
return lambda X: other.TreeMapleExplainer(model, data).attributions(X, multiply_by_input=False)
def deep_shap(model, data):
"""Deep SHAP (DeepLIFT)"""
if isinstance(model, KerasWrap):
model = model.model
explainer = DeepExplainer(model, kmeans(data, 1).data)
def f(X):
phi = explainer.shap_values(X)
if isinstance(phi, list) and len(phi) == 1:
return phi[0]
else:
return phi
return f
def expected_gradients(model, data):
"""Expected Gradients"""
if isinstance(model, KerasWrap):
model = model.model
explainer = GradientExplainer(model, data)
def f(X):
phi = explainer.shap_values(X)
if isinstance(phi, list) and len(phi) == 1:
return phi[0]
else:
return phi
return f