我训练一个线性模型来预测房价,然后我将手动计算的 Shapley 值与
SHAP
库返回的值进行比较,它们略有不同。
我的理解是,对于线性模型,Shapley 值是给定的通过:
coeff * features for obs - coeffs * mean(features in training set)
或者如SHAP文档中所述:
coef[i] * (x[i] - X.mean(0)[i])
,其中i是一个特征。
问题是,为什么SHAP返回与手动计算不同的值?
这里是代码:| ||返回结果:
import pandas as pd
from sklearn.datasets import fetch_california_housing
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler
import shap
X, y = fetch_california_housing(return_X_y=True, as_frame=True)
X = X.drop(columns = ["Latitude", "Longitude", "AveBedrms"])
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.3, random_state=0,
)
scaler = MinMaxScaler().set_output(transform="pandas").fit(X_train)
X_train = scaler.transform(X_train)
X_test = scaler.transform(X_test)
linreg = LinearRegression().fit(X_train, y_train)
coeffs = pd.Series(linreg.coef_, index=linreg.feature_names_in_)
X_test.reset_index(inplace=True, drop=True)
obs = 6188
# manual shapley calculation
effect = coeffs * X_test.loc[obs]
effect - coeffs * X_train.mean()
SHAP 库返回的内容略有不同:
MedInc 0.123210
HouseAge -0.459784
AveRooms -0.128162
Population 0.032673
AveOccup -0.001993
dtype: float64
这里结果:
explainer = shap.LinearExplainer(linreg, X_train)
shap_values = explainer(X_test)
shap_values[obs]
它被设置为忽略交互:
.values =
array([ 0.12039244, -0.47172515, -0.12767778, 0.03473923, -0.00251017])
.base_values =
2.0809714707337523
.data =
array([0.25094137, 0.01960784, 0.06056066, 0.07912217, 0.00437137])
返回
explainer.feature_perturbation
returning
'interventional'
SHAP 库返回的值与手动计算的值之间的细微差异是由于 SHAP 包中
LinearExplainer
使用的实现造成的。虽然两种方法都基于 Shapley 值,但 SHAP 的实现包含了一些细微的调整,以提高效率和处理各种情况。
以下是差异的一些可能原因:
-
特征相关性: 你的手动计算假设特征之间相互独立。但是,如果特征之间存在相关性,则 SHAP 库会考虑到这一点来提供更准确的 Shapley 值。它不会简单地将每个特征的贡献相加,而是会考虑特征之间的交互。
-
基值: SHAP 库计算一个基值,该值代表所有特征缺失时模型的平均预测。此基值随后用于计算 Shapley 值。你的手动计算似乎没有考虑基值。在你的代码中,
shap_values[obs]
的.base_values
属性表示该基值。 -
正则化: 如果你的线性模型包含正则化(例如 L1 或 L2 正则化),则 SHAP 库会在计算 Shapley 值时考虑到这一点。你的手动计算可能不会考虑到正则化的影响。
-
数值精度: 在两种方法中进行计算时,舍入误差和数值精度也可能导致微小的差异。
要使手动计算更接近 SHAP 库的结果,你需要考虑以下因素:
- 基值: 从 SHAP 库中获取基值,并将其添加到手动计算中。
- 特征相关性: 如果特征之间存在相关性,则你的手动计算需要考虑这一点。这可能很复杂,需要对 Shapley 值有更深入的了解。
一般来说,建议使用 SHAP 库来计算 Shapley 值,因为它提供了更稳健且准确的实现,尤其是在处理复杂模型或特征相关性时。 但是,了解两种方法之间的差异有助于深入了解 SHAP 值的工作原理。
标签:python,machine-learning,shap,xai From: 78796974