当将xgbTree方法与Caret一起使用时,非树模型错误,并且在应用varImp函数时将权重设置为目标变量

问题描述

当我使用Caret包中的“火车”功能创建模型以进行权重的梯度增强时,使用“ varImp”功能表示未检测到树模型时会出现错误。但是当我去掉砝码后,它就起作用了。

下面的代码会产生错误

set.seed(123)

model_weights <- ifelse(modelo_df_sseg$FATALIDADES == 1,yes = (1/table(modelo_df_sseg$FATALIDADES)[2]) * 0.5,no = (1/table(modelo_df_sseg$FATALIDADES)[1]) * 0.5
                        )

model <- train(
  as.factor(FATALIDADES) ~.,data = modelo_df_sseg,method = "xgbTree",trControl = trainControl("cv",number = 10),weights = model_weights
  )

varImp(model)

但是,如果我不施加重量,它将起作用。

为什么varImp无法识别我的树?

编辑04-SEP-2020

在注释部分,滥用提示使用wts代替权重。现在我得到以下错误

Error in nominalTrainWorkflow(x = x,y = y,wts = weights,info = trainInfo,: formal argument 'wts' matched by multiple actual arguments

我使用R内置数据集编写了一个代码,因此您可以自己对其进行测试:

set.seed(123)

basex <- Arrests

model_weights <- ifelse(basex$released == 2,yes = (1/table(basex$released)[2]) * 0.5,no = (1/table(basex$released)[1]) * 0.5
                        )

y = basex$released
x = basex
tc = trainControl("cv",number = 10)

mtd = "xgbTree"
model <- train(
  x,y,method = mtd,trControl = tc,wts = model_weights,verbose = TRUE
  )

也许我在创建权重向量错误。但是我找不到有关'wts'参数的任何文档。

解决方法

示例代码有几个问题。

在插入符号中施加权重的正确方法是使用weights的{​​{1}}参数。

我在建议使用自变量train的注释中弄错了。我的错误归因于xgbTree source,尤其是以下行:

wts

表明if (!is.null(wts)) xgboost::setinfo(x,'weight',wts) 可能是正确的答案。

让我们仔细研究一下示例并解决所有问题

wts

在这里,我们看到“是”结果比“否”结果更为频繁。这将歪曲预测的概率,并偏向于倾向于预测“是”的模型。解决它的一种方法是赋予“否”观察更大的权重。对于“否”观察,有意义的权重将是“是”类别的比例,对于“是”观察有意义的权重将是“否”类别的比例:

library(caret)
library(car) #for the data set
library(tidyverse) #because I like to use it

data(Arrests)
basex <- Arrests


table(basex$released) #released is the outcome class

  No  Yes 
 892 4334 

权重之和为1

model_weights <- ifelse(basex$released == "Yes",table(basex$released)[1]/nrow(basex),table(basex$released)[2]/nrow(basex))

“是”更为常见,因此我们的权重较小。

从上面可以看出,数据框具有几个类别的预测变量(例如颜色,性别...)。 head(data.frame(basex,weights = model_weights)) released colour year age sex employed citizen checks weights 1 Yes White 2002 21 Male Yes Yes 3 0.170685 2 No Black 1999 17 Male Yes Yes 3 0.829315 3 Yes White 2000 24 Male Yes Yes 3 0.170685 4 No Black 2000 46 Male Yes Yes 1 0.829315 5 Yes Black 1999 27 Female Yes Yes 1 0.170685 6 Yes Black 1998 16 Female Yes Yes 0 0.170685 无法处理它们,因此您需要在建模之前将它们转换为数字。将分类预测变量转换为数字的一种方法是伪编码。还有其他方法,但这不在此答案的范围内。

要使用伪编码:

xgbTree

现在我们有了权重x和y

由于我将在以下拟合多个模型,因此我将首先创建重采样折叠,并在每次通话中使用它们进行训练,因此它们不会有所不同。

dummies <- dummyVars(released ~ .,data = basex)
x <- predict(dummies,newdata = basex)
head(x)
colour.Black colour.White year age sex.Female sex.Male employed.No employed.Yes citizen.No citizen.Yes checks
1            0            1 2002  21          0        1           0            1          0           1      3
2            1            0 1999  17          0        1           0            1          0           1      3
3            0            1 2000  24          0        1           0            1          0           1      3
4            1            0 2000  46          0        1           0            1          0           1      1
5            1            0 1999  27          1        0           0            1          0           1      1
6            1            0 1998  16          1        0           0            1          0           1      0

y <- basex$released

由于班级频率不平衡,我将使用folds <- createFolds(basex$released,10) ,以便我们可以看到经过训练的模型的敏感性和特异性

twoClassSummary

#没有错误

tc <- trainControl(method = "cv",number = 10,summaryFunction = twoClassSummary,index = folds,#predefined folds
                   classProbs = TRUE) #needed for twoClassSummary

mtd <- "xgbTree"

model <- train(x = x,y = y,method = mtd,trControl = tc,weights = model_weights,verbose = TRUE,metric = "ROC")

在这里我们看到,如果使用模型权重,则具有最大AUC的模型具有0.6185944的敏感性和0.693945的特异性。

没有重量

model$results %>%
  filter(ROC == max(ROC))
  eta max_depth gamma colsample_bytree min_child_weight subsample nrounds       ROC      Sens     Spec       ROCSD     SensSD     SpecSD
1 0.3         1     0              0.8                1         1      50 0.7031076 0.6185944 0.693945 0.009074758 0.03516597 0.01536701

#没有错误

model2 <- train(x = x,metric = "ROC")

没有权重的模型的灵敏度为0.1000325,特异性为0.9713885。

因此有意义的权重参数固定了模型趋势,始终可以预测“是”。