我有一个缺少数据的数据集。它们被编码为 NaN。这非常适合使用 XGBoost 进行模型拟合。当我想理解模型,用SHAP散点图分析模型重要性时,我不确定什么是正确的用法。
考虑下面的综合示例:
import numpy as np, scipy.special, xgboost as xgb, shap
rng = np.random.default_rng(0)
def gendata(n):
X = rng.normal(size=(n,1))
y = np.sin(X[:,0]) + rng.normal(size=n)
X[:n//2,0] = np.nan
y = (rng.random(size=n) < scipy.special.expit(y)).astype(int)
dmatrix = xgb.DMatrix(X,label=y,feature_names=['X0'])
return X,y, dmatrix
X,y,dmat = gendata(10)
model = xgb.train({'objective':'reg:squarederror','booster':'gbtree'}, dmat)
explainer = shap.Explainer(model,feature_names=dmat.feature_names)
explanation = explainer(dmat);shap.plots.scatter(explanation)
explanation = explainer(X,y);shap.plots.scatter(explanation)
它产生以下两个散点图。 使用原始 numpy 数组时,该图将缺失的数据显示为地毯图标记。这似乎是正确的。当使用
xgb.DMatrix
时,它的插补为零。
explanation
对象正确保存源数据(dmat
中的稀疏矩阵和 X,y
情况中的 numpy 数组)。我认为 scatter 函数中的某个地方有一个 to_dense
调用,它搞乱了一切。
如果我只有
xgb.DMatrix
可用,我应该如何进行分散?
如果我只有 DMA
出现此问题的原因是,SHAP 的
scatter
函数在使用 xgb.DMatrix
时可能无法正确处理缺失数据,因为它可能会将稀疏矩阵转换为稠密矩阵,从而导致零插补。要正确显示缺失值(例如,作为地毯图标记),在计算 SHAP 值时应使用原始输入数据(numpy
数组或 pandas.DataFrame
)而不是 xgb.DMatrix
。虽然可以使用 DMatrix
训练模型,但将原始 X
传递给 SHAP 解释器可确保正确处理 NaN
值和准确的散点图。