存储在'object'和'newdata'中的要素名称不同!当使用LIME软件包解释R中的xgboost模型时
我试图用莱姆来解释我用XGboost训练过的二进制分类模型。从LIME调用explain函数时,我遇到了一个错误,这意味着我的模型或解释器中的列与我试图解释预测的新数据不匹配 这对于LIME来说确实演示了一个带有xgboost的版本,但是这是一个文本问题,与我的表格数据有点不同。这似乎遇到了相同的错误,但对于文档术语矩阵也是如此,这似乎掩盖了我的案例的解决方案。我用mtcars制作了一个最小的例子,它产生的错误与我在自己更大的数据集中得到的错误完全相同存储在'object'和'newdata'中的要素名称不同!当使用LIME软件包解释R中的xgboost模型时,r,xgboost,lime,R,Xgboost,Lime,我试图用莱姆来解释我用XGboost训练过的二进制分类模型。从LIME调用explain函数时,我遇到了一个错误,这意味着我的模型或解释器中的列与我试图解释预测的新数据不匹配 这对于LIME来说确实演示了一个带有xgboost的版本,但是这是一个文本问题,与我的表格数据有点不同。这似乎遇到了相同的错误,但对于文档术语矩阵也是如此,这似乎掩盖了我的案例的解决方案。我用mtcars制作了一个最小的例子,它产生的错误与我在自己更大的数据集中得到的错误完全相同 library(pacman) p_loa
library(pacman)
p_load(tidyverse)
p_load(xgboost)
p_load(Matrix)
p_load(lime)
### Prepare data with partition
df <- mtcars %>% rownames_to_column()
length <- df %>% nrow()
df_train <- df %>% select(-rowname) %>% head((length-10))
df_test <- df %>% select(-rowname) %>% tail(10)
### Transform data into matrix objects for XGboost
train <- list(sparse.model.matrix(~., data = df_train %>% select(-vs)), (df_train$vs %>% as.factor()))
names(train) <- c("data", "label")
test <- list(sparse.model.matrix(~., data = df_test %>% select(-vs)), (df_test$vs %>% as.factor()))
names(test) <- c("data", "label")
dtrain <- xgb.DMatrix(data = train$data, label=train$label)
dtest <- xgb.DMatrix(data = test$data, label=test$label)
### Train model
watchlist <- list(train=dtrain, test=dtest)
mod_xgb_tree <- xgb.train(data = dtrain, booster = "gbtree", eta = .1, nrounds = 15, watchlist = watchlist)
### Check prediction works
output <- predict(mod_xgb_tree, test$data) %>% tibble()
### attempt lime explanation
explainer <- df_train %>% select(-vs) %>% lime(model = mod_xgb_tree) ### works, no error or warning
explanation <- df_test %>% select(-vs) %>% explain(explainer, n_features = 4) ### error, Features stored names in `object` and `newdata` are different!
names_test <- test$data@Dimnames[[2]] ### 10 names
names_mod <- mod_xgb_tree$feature_names ### 11 names
names_explainer <- explainer$feature_type %>% enframe() %>% pull(name) ### 11 names
### see whether pre-processing helps
my_preprocess <- function(df){
data <- df %>% select(-vs)
label <- df$vs
test <<- list(sparse.model.matrix( ~ ., data = data), label)
names(test) <<- c("data", "label")
dtest <- xgb.DMatrix(data = test$data, label=test$label)
dtest
}
explanation <- df_test %>% explain(explainer, preprocess = my_preprocess(), n_features = 4) ### Error in feature_distribution[[i]] : subscript out of bounds
### check that the preprocessing is working ok
dtest_check <- df_test %>% my_preprocess()
output_check <- predict(mod_xgb_tree, dtest_check)
我假设,因为解释程序只有原始预测列的名称,而处于转换状态的测试数据也有一个截取列,这就是问题的原因。我只是还没有想出一个好办法来防止这种情况发生。任何帮助都将不胜感激。我认为一定有一个简洁的解决方案。如果您查看此页面,您将看到一些R用户可能会收到以下错误消息:存储在object和newdata中的功能名称不同
以下是此页面中与错误消息相关的代码:
predict.xgb.Booster <- function(object, newdata, missing = NA, outputmargin = FALSE, ntreelimit = NULL,predleaf = FALSE, predcontrib = FALSE, approxcontrib = FALSE, predinteraction = FALSE,reshape = FALSE, ...)
object <- xgb.Booster.complete(object, saveraw = FALSE)
if (!inherits(newdata, "xgb.DMatrix"))
newdata <- xgb.DMatrix(newdata, missing = missing)
if (!is.null(object[["feature_names"]]) &&
!is.null(colnames(newdata)) &&
!identical(object[["feature_names"]], colnames(newdata)))
stop("Feature names stored in `object` and `newdata` are different!")
由于上面的代码,您可以自己使用数据设置object和newdata,您可以通过查看object[[feature_names]]和colnamesnewdata之间的差异来解决此问题。可能是某些列的显示顺序不一致或其他原因。在新数据集中尝试此操作
colnames(test)<- make.names(colnames(test))
newdataset<- test %>% mutate_all(as.numeric)
newdataset<- as.matrix(newdataset)
nwtest<-xgb.DMatrix(newdataset)
为了防止出现截取列,在为测试数据创建稀疏矩阵时,需要稍微更改代码。 更改行:
test <- list(sparse.model.matrix( ~ ., data = data), label)
致:
希望这有帮助我也遇到了同样的问题,但列不是按字母顺序排列的。为了解决这个问题,我将df_测试中的列名顺序与df_列匹配,以便列名的顺序相同 按照与df_系列相同的顺序创建df_测试列编号列表:
idx<- match(colnames(df_train), colnames(df_test))
使用以下列顺序创建新的df_测试文件:
df_test_match <- df_test[,idx]
谢谢,我试了一下,但似乎不起作用。我的第一行有问题。。我应该叫哪个物体名字
idx<- match(colnames(df_train), colnames(df_test))
df_test_match <- df_test[,idx]