我想在使用caret包进行GBM运行时使用AUPRC作为性能度量。我如何使用自定义指标如auprc?

我试图将AUPRC作为我的gbm模型拟合的自定义指标,因为我有一个不平衡的分类器。然而,当我尝试加入自定义指标时,我得到了代码中提到的错误。不确定我做错了什么。

此外,当我直接运行auprcSummary()时,它可以正常工作。但当我尝试将其纳入train()时,它会报错。

     library(dplyr) # 用于数据操作     library(caret) # 用于模型构建     library(pROC) # 用于AUC计算     library(PRROC) # 用于精确度-召回率曲线计算    auprcSummary <- function(data, lev = NULL, model = NULL){      index_class2 <- data$Class == "Class2"      index_class1 <- data$Class == "Class1"      the_curve <- pr.curve(data$Class[index_class2],                    data$Class[index_class1],                    curve = FALSE)      out <- the_curve$auc.integral      names(out) <- "AUPRC"      out      }    ctrl <- trainControl(method = "repeatedcv",                 number = 10,                 repeats = 5,                 summaryFunction = auprcSummary,                 classProbs = TRUE)    set.seed(5627)    orig_fit <- train(Class ~ .,              data = toanalyze.train,              method = "gbm",              verbose = FALSE,              metric = "AUPRC",              trControl = ctrl)

这是我得到的错误:

     Error in order(scores.class0) : argument 1 is not a vector  

这是因为pr.curve()只接受数值向量作为输入(分数/概率)吗?


回答:

我认为这种方法可以产生一个合适的自定义摘要函数:

library(caret) library(pROC) library(PRROC)library(mlbench) #用于数据集data(Ionosphere)

pr.curve函数中,分类分数可以分别为每个类别的数据点提供,即对于正/前景类的数据点作为scores.class0,对于负/背景类的数据点作为scores.class1;或者所有数据点的分类分数作为scores.class0提供,标签作为数值(正类为1,负类为0)作为weights.class0提供(我从函数帮助中复制了这段内容,如果不清楚我道歉)。

我选择了后者 – 在scores.class0中提供所有数据点的概率,并在weights.class0中提供类别分配。

caret指出,如果trainControl对象的classProbs参数设置为TRUE,data中将包含额外的列,这些列包含类别概率。因此,对于Ionosphere数据,列goodbad应该存在:

levels(Ionosphere$Class)#output[1] "bad"  "good"

要转换为0/1标签,可以简单地执行:

as.numeric(Ionosphere$Class) - 1

good将变为1
bad将变为0

现在我们有了自定义函数所需的所有数据

auprcSummary <- function(data, lev = NULL, model = NULL){  prob_good <- data$good #获取good类的概率  the_curve <- pr.curve(scores.class0 = prob_good,                        weights.class0 = as.numeric(data$obs)-1, #提供类别标签为0/1                        curve = FALSE)  out <- the_curve$auc.integral  names(out) <- "AUPRC"  out}

与其使用data$good,这只适用于这个数据集,可以提取类别名称并使用它来获取所需的列:

  lvls <- levels(data$obs)  prob_good <- data[,lvls[2]]

每次更新summaryFunction时,都需要更新trainControl对象,这一点很重要。

ctrl <- trainControl(method = "repeatedcv",                     number = 10,                     repeats = 5,                     summaryFunction = auprcSummary,                     classProbs = TRUE)orig_fit <- train(y = Ionosphere$Class, x = Ionosphere[,c(1,3:34)], #省略第2列以避免与数据集相关的许多警告                  method = "gbm",                  verbose = FALSE,                  metric = "AUPRC",                  trControl = ctrl)orig_fit$results#output  shrinkage interaction.depth n.minobsinnode n.trees     AUPRC    AUPRCSD1       0.1                 1             10      50 0.9722775 0.035248824       0.1                 2             10      50 0.9758017 0.031433797       0.1                 3             10      50 0.9739880 0.033169232       0.1                 1             10     100 0.9786706 0.025021835       0.1                 2             10     100 0.9817447 0.022768838       0.1                 3             10     100 0.9772322 0.033010643       0.1                 1             10     150 0.9809693 0.020786016       0.1                 2             10     150 0.9824430 0.022843619       0.1                 3             10     150 0.9818318 0.02287886

看起来合理

Related Posts

Keras Dense层输入未被展平

这是我的测试代码: from keras import…

无法将分类变量输入随机森林

我有10个分类变量和3个数值变量。我在分割后直接将它们…

如何在Keras中对每个输出应用Sigmoid函数?

这是我代码的一部分。 model = Sequenti…

如何选择类概率的最佳阈值?

我的神经网络输出是一个用于多标签分类的预测类概率表: …

在Keras中使用深度学习得到不同的结果

我按照一个教程使用Keras中的深度神经网络进行文本分…

‘MatMul’操作的输入’b’类型为float32,与参数’a’的类型float64不匹配

我写了一个简单的TensorFlow代码,但不断遇到T…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注