背景资料
我在我的训练数据上拟合一个分类器。当测试我拟合的最佳估计量时,我预测其中一个类的概率。我按照概率降序排列我的X_test和y_test。
问题
我想了解哪些特征对于分类器来说是重要的(以及在多大程度上),以便分类器只预测整体概率最高的500个预测,而不是每个预测。
y_test_probas = clf.predict_proba(X_test)[:, 1]
explainer = shap.Explainer(clf, X_train) # <-- here I put the X which the classifier was trained on?
top_n_indices = np.argsort(y_test_probas)[-500:]
shap_values = explainer(X_test.iloc[top_n_indices]) # <-- here I put the X I want the SHAP values for?
shap.plots.bar(shap_values)
不幸的是,shap documentation (bar plot)不包括这种情况。有两件事是不同的:
1.它们使用训练分类器的数据(我想使用测试分类器的数据)
1.他们使用整个X而不是其中的一部分(我想只使用部分数据)
最小可重复示例
import numpy as np
import pandas as pd
import shap
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
# Load the Titanic Survival dataset
data = pd.read_csv("https://web.stanford.edu/class/archive/cs/cs109/cs109.1166/stuff/titanic.csv")
# Preprocess the data
data = data.drop(["Name"], axis=1)
data = data.dropna()
data["Sex"] = (data["Sex"] == "male").astype(int)
# Split the data into predictors (X) and response variable (y)
X = data.drop("Survived", axis=1)
y = data["Survived"]
# Split the dataset into train and test sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# Fit a logistic regression classifier
clf = RandomForestClassifier().fit(X_train, y_train)
# Get the predicted class probabilities for the positive class
y_test_probas = clf.predict_proba(X_test)[:, 1]
# Select the indices of the top 500 test samples with the highest predicted probability of the positive class
top_n_indices = np.argsort(y_test_probas)[-500:]
# Initialize the Explainer object with the classifier and the training set
explainer = shap.Explainer(clf, X_train)
# Compute the SHAP values for the top 500 test samples
shap_values = explainer(X_test.iloc[top_n_indices, :])
# Plot the bar plot of the computed SHAP values
shap.plots.bar(shap_values)
我不想知道分类器如何决定所有预测,而是决定概率最高的预测。该代码适合回答这个问题吗?如果不适合,合适的代码是什么样子的?
1条答案
按热度按时间cbeh67ev1#
首先:你的代码是正确的,有一个潜在的点要讨论(见下文)。
SHAP值如何计算?
您的模型是线性的,因此
shap.Explainer()
使用最简单形式的线性解释器。这意味着:观察的特征j的SHAP值简单地为coef_j *(value_mean_j),
何处
shap.Explainer()
的数据集的100个随机采样观察值中的特征j的平均值大谜团:计算平均值比二次采样便宜得多,那么为什么线性解释器在这种情况下要进行二次采样呢?哦,好吧...
示例
我们可以通过仅使用训练数据的前100行来验证上述计算,因此不进行二次采样:
这导致
我们可以通过手动计算轻松重建:
带输出:
讨论要点
解释器使用训练数据中随机抽取的100行数据来计算均值。这些数据对于您想要解释的数据来说可能非常不具有代表性,因此将背景数据传递给
shap.Explainer()
而不是感兴趣的数据X_test.iloc[top_n_indices, :]
可能更正确。