如何解决当将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。
因此有意义的权重参数固定了模型趋势,始终可以预测“是”。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。