我无法使用 R 中的
iml
包来查找 glmnet
模型的 shapley 值。
问题似乎可能与以下事实有关:
glmnet()
和 predict.glmnet()
期望矩阵,而 x.interest
中的 iml::Shapley$new()
参数期望数据帧,因此某些内容被错误转换,但我不确定。
我尝试过的最合理的方法如下。由于
iml::Predictor()
文档中的以下注释,我确保我的预测函数返回两个类的估计概率:“注意:在分类的情况下,模型应为每个类返回一列以及类概率。”
library(dplyr)
library(iml)
library(glmnet)
df <- filter(iris, Species != 'setosa')
X <- as.matrix(select(train, -Species))
y <- droplevels(df$Species)
fit <- glmnet(X, y, family = 'binomial', lambda = 0.03)
predfun <- function(model, newdata) {
preds <- predict(model, as.matrix(newdata), type = 'response') # probabilities
return(cbind(1 - preds, preds)) # for both classes
}
# Pass data frames, as requested
mod <- Predictor$new(fit, as.data.frame(X), predict.function = predfun)
shapley <- Shapley$new(mod, x.interest = as.data.frame(X[1, ]))
这给了我以下内容:
Error in predict.glmnet(model, as.matrix(newdata), type = "response"): The number of variables in newx must be 4
我不太确定传递给没有四个变量的
predict.glmnet()
的内容(它似乎与我尝试过的事情的拦截无关)。我查看了 Shapley$new()
的源代码,并且通过 browser()
的调用也进行了相当长的一段时间,但无法想出任何有用的东西。
有什么想法吗? 谢谢!
不是 100% 确定如何解决这个 API 噩梦......
您可以尝试精确的 KernelSHAP:
library(dplyr)
library(glmnet)
df <- filter(iris, Species != 'setosa')
X <- as.matrix(select(df, -Species))
y <- droplevels(df$Species)
fit <- glmnet(X, y, family = 'binomial', lambda = 0.03)
library(kernelshap)
library(shapviz)
library(ggplot2)
library(patchwork)
s <- shapviz(kernelshap(fit, X, bg_X = X))
sv_importance(s, kind = "bee", show_numbers = TRUE)
sv_dependence(s, colnames(X), color_var = NULL) &
ylim(-4, 4)
sv_waterfall(s, row_id = 1)