FYI, here’s how I got at least the model-agnostic KernelExplainer from shap to run in a notebook without errors on a tabular learner (model/data on gpu with both categorical and continuous variables):
# learn = tabular_learner(...)
# learn.fit_one_cycle(...)
import numpy as np
import pandas as pd
import shap
shap.initjs()
def pred(data):
device = learn.data.device
cat_cols = len(learn.data.train_ds.x.cat_names)
cont_cols = len(learn.data.train_ds.x.cont_names)
x_cat = torch.from_numpy(data[:, :cat_cols]).to(device, torch.int64)
x_cont = torch.from_numpy(data[:, -cont_cols:]).to(device, torch.float32)
pred_proba = learn.model(x_cat, x_cont).detach().to('cpu').numpy()
return pred_proba
def shap_data(data):
X_train, y_train = data.one_batch(denorm=False, cpu=False)
X_test, y_test = data.one_batch(denorm=False, cpu=False)
cols = data.train_ds.x.col_names
X_train = pd.DataFrame(np.concatenate([v.to('cpu').numpy() for v in X_train], axis=1), columns=cols)
X_test = pd.DataFrame(np.concatenate([v.to('cpu').numpy() for v in X_test], axis=1), columns=cols)
return X_train, X_test
X_train, X_test = shap_data(learn.data)
e = shap.KernelExplainer(pred, X_train)
shap_values = e.shap_values(X_test, nsamples=100, l1_reg=False)
shap.force_plot(e.expected_value[0], shap_values[0], X_test)
shap.summary_plot(shap_values, X_test, plot_type="bar")
This grabs two batches from the training set as X_train and X_test for shap.