def kshap_explainer(lr_classifier, adult_data): predictor = predict_fcn(predict_type='proba', clf=lr_classifier, preproc=adult_data['preprocessor']) kshap = KernelShap(predictor=predictor, link='logit', feature_names=adult_data['metadata']['feature_names']) kshap.fit(adult_data['X_train'][:100]) return kshap
def explain(model, TrainDF, TestDF, y_col, normalize=True): X_Train = np.array(TrainDF.drop(columns=[y_col], axis=1).to_numpy()) y_Train = np.array(TrainDF[[y_col]].to_numpy()) X_Test = np.array(TestDF.drop(columns=[y_col], axis=1).to_numpy()) y_Test = np.array(TestDF[[y_col]].to_numpy()) if normalize: X_Train = preprocessing.scale(X_Train) X_Test = preprocessing.scale(X_Test) model.fit(X_Train, y_Train.ravel()) pred_fcn = model.decision_function np.random.seed(0) svm_explainer = KernelShap(pred_fcn) svm_explainer.fit(shap.kmeans(X_Train, 10)) svm_explanation = svm_explainer.explain(X_Test, l1_reg=False) feature_names = TrainDF.columns.drop([y_col]) classes = set(TrainDF[y_col]) classes_it = iter(classes) for class_id in range(0, len(classes)): print(next(classes_it)) plt.figure() shap.summary_plot(svm_explanation.shap_values[class_id], X_Test, feature_names, show=False) plt.savefig( f'shap_summary_plot_binary-{class_id}{"-normalized" if normalize else ""}.png' ) plt.figure() shap.summary_plot(svm_explanation.shap_values, X_Test, feature_names, show=False) plt.savefig( f'shap_summary_plot_binary_X{"-normalized" if normalize else ""}.png')
def make_kernel_shap(dirname: Optional[Path] = None) -> KernelShap: np.random.seed(0) # load data wine = load_wine() data = wine.data target = wine.target target_names = wine.target_names feature_names = wine.feature_names # train classifier X_train, X_test, y_train, y_test = train_test_split(data, target, test_size=0.2, random_state=0) scaler = StandardScaler().fit(X_train) X_train_norm = scaler.transform(X_train) X_test_norm = scaler.transform(X_test) classifier = SVC( kernel="rbf", C=1, gamma=0.1, decision_function_shape="ovr", # n_cls trained with data from one class as positive # and remainder of data as neg random_state=0, ) classifier.fit(X_train_norm, y_train) # build kernel shap model pred_fcn = classifier.decision_function svm_explainer = KernelShap(pred_fcn) svm_explainer.fit(X_train_norm) if dirname is not None: svm_explainer.save(dirname) return svm_explainer