使用插入符号包(varImp)计算分类变量的变量重要性时出错

使用插入符号包(varImp)计算分类变量的变量重要性时出错,r,r-caret,feature-selection,R,R Caret,Feature Selection,我一直在尝试使用caret包中的varImp函数计算具有混合比例特征的模型的变量重要性。我尝试了很多方法,包括重命名和用数字编码我的等级。在每种情况下,我都会得到以下错误: Error in auc3_(actual, predicted, ranks) : Not compatible with requested type: [type=character; target=double]. 以下虚拟示例应说明我的观点(编辑以反映@StupidWolf的更正): 库(插入符号) #创建

我一直在尝试使用
caret
包中的
varImp
函数计算具有混合比例特征的模型的变量重要性。我尝试了很多方法,包括重命名和用数字编码我的等级。在每种情况下,我都会得到以下错误:

Error in auc3_(actual, predicted, ranks) : 
  Not compatible with requested type: [type=character; target=double].
以下虚拟示例应说明我的观点(编辑以反映@StupidWolf的更正):

库(插入符号)
#创建小型虚拟数据集
种子集(124)
虚拟数据=数据帧(标签=系数(样本(c(“a”,“b”),40,替换=真)))
虚拟数据$pred1=ifelse(虚拟数据$Label==“a”,rnorm(40,-.5,2),rnorm(40,5,2))
伪随机数据$pred2=系数(如果其他(伪随机数据$Label==“a”、rbinom(40,1,0.3)、rbinom(40,1,0.7)))
#检查varImp

control.lvq注意,可以通过用(d-1)维指示符编码替换顺序特征(具有d级)来避免此问题:

model.matrix(~dummy_data$pred2-1)[,1:(length(levels(dummy_data$pred2)-1)]

然而,为什么varImp不能自动处理这个问题?此外,这还有一个缺点,即它会为每个d-1指标生成一个重要性分数,而不是原始功能的一个统一重要性分数。

在lvq上调用varImp时,它默认为
filterVarImp()
,因为此模型没有特定的变量重要性。现在,如果您检查:

对于两类问题,将一系列截止值应用于 预测数据预测类。敏感性和特异性 计算每个截止点的ROC,并计算ROC曲线

现在,如果您读取将数据馈送到
filterVarImp()
,则它是原始的数据帧,而不是来自预处理的任何内容

这意味着在原始数据中,如果您有一个变量是一个因子,它无法剪切该变量,它将抛出如下错误:

filterVarImp(data.frame(dummy_data$pred2),dummy_data$Label)
Error in auc3_(actual, predicted, ranks) : 
  Not compatible with requested type: [type=character; target=double].
因此,使用我的示例,正如您所指出的,您需要对其进行onehot编码:

set.seed(111)
dummy_data = data.frame(Label = rep(c("a","b"),each=20))
dummy_data$pred1 = rnorm(40,rep(c(-0.5,0.5),each=20),2)
dummy_data$pred2 = rbinom(40,1,rep(c(0.3,0.7),each=20))
dummy_data$pred2 = factor(dummy_data$pred2)

control.lvq <- caret::trainControl(method="repeatedcv", number=10, repeats=3)

ohe_data = data.frame(
            Label = dummy_data$Label,
            model.matrix(Label ~ 0+.,data=dummy_data))

model.lvq <- caret::train(Label~., data=ohe_data, 
                          method="lvq", preProcess="scale",
                       trControl=control.lvq)

caret::varImp(model.lvq, scale=FALSE)  

ROC curve variable importance

       Importance
pred1      0.6575
pred20     0.6000
pred21     0.6000
set.seed(111)
虚拟数据=数据帧(标签=代表(c(“a”、“b”),每个=20))
虚拟数据$pred1=rnorm(40,rep(c(-0.5,0.5),每个=20),2)
虚拟数据$pred2=rbinom(40,1,代表(c(0.3,0.7),每个=20))
虚拟_数据$pred2=系数(虚拟_数据$pred2)

感谢@StupidWolf指出了预测器的问题。我以你为例。但是,我仍然收到一条错误消息:`` y中的error-mean(y,rm.na=TRUE):二进制运算符的非数字参数另外:警告消息:in-mean.default(y,rm.na=TRUE):参数不是数字或逻辑的:返回na``既然它似乎对您有效,这可能是版本问题吗?我在R版本4.0.3上运行,插入符号在版本6.0-86上运行。在将Label和pred2设置为factors后,我得到了与我的原始帖子中描述的相同的错误。与R版本无关。。检查下一次@hanibalOk你在做什么。我希望caret能够在内部处理分类变量,并为分类特征计算单个变量的重要性。感谢你澄清事实并非如此。我在我贴出的答案中详细说明了这一点——可能是因为它被按下了,所以不太清楚;-)。谢谢你的链接。我不知道预处理也适用于分类数据。事实上,在删除caret::train中的preProcess参数后,这个问题对我来说似乎仍然存在(至少没有先对分类数据进行编码)。。好的,我必须仔细阅读代码。插入符号::varImp使用的AUC函数无法处理该因子
set.seed(111)
dummy_data = data.frame(Label = rep(c("a","b"),each=20))
dummy_data$pred1 = rnorm(40,rep(c(-0.5,0.5),each=20),2)
dummy_data$pred2 = rbinom(40,1,rep(c(0.3,0.7),each=20))
dummy_data$pred2 = factor(dummy_data$pred2)

control.lvq <- caret::trainControl(method="repeatedcv", number=10, repeats=3)

ohe_data = data.frame(
            Label = dummy_data$Label,
            model.matrix(Label ~ 0+.,data=dummy_data))

model.lvq <- caret::train(Label~., data=ohe_data, 
                          method="lvq", preProcess="scale",
                       trControl=control.lvq)

caret::varImp(model.lvq, scale=FALSE)  

ROC curve variable importance

       Importance
pred1      0.6575
pred20     0.6000
pred21     0.6000