R中的caret包:最大化手动定义的训练集(分类)正类的灵敏度

8

简短版:

有没有一种方法可以指示Caret训练回归模型

  1. 使用用户定义的标签作为“正类标签”?
  2. 在训练期间优化模型的灵敏度(而不是ROC)?

长版本:

我有一个数据框

> feature1 <-                 c(1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0)
> feature2 <-                 c(1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1)
> feature3 <-                 c(0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0)
> TARGET <- factor(make.names(c(1,0,1,1,0,0,1,0,1,1,1,0,1,0,0,0,1,0,1,1)))
> df <- data.frame(feature1, feature2, feature3, TARGET)

模型训练的实现方式如下:

> ctrl <- trainControl(
+     method="repeatedcv",
+     repeats = 2)
> 
> tuneGrid <- expand.grid(k = c(2,5,7))
> 
> tune <- train(
+     TARGET ~ .,
+     metric = '???',
+     maximize = TRUE,
+     data = df,
+     method = "knn", 
+     trControl = ctrl, 
+     preProcess = c("center","scale"), 
+     tuneGrid = tuneGrid
+ )
> sclasses <- predict(tune, newdata = df)
> df$PREDICTION <- make.names(factor(sclasses), unique = FALSE, allow_ = TRUE)

我希望最大化灵敏度=精度=A / ( A + C )

enter image description here

在这张图片中,Event(应该)在我的情况下是X1 = 执行的操作。但是caret使用X0 = 未执行操作

我可以通过使用positive参数来设置混淆矩阵的正类。

> confusionMatrix(df$PREDICTION, df$TARGET, positive = "X1")

但是在训练时有没有办法设置这个(最大化灵敏度)呢?

我已经检查过是否有其他适合我的需求的指标,但是我在文档中没有找到任何一个。我需要为trainControl实现自己的summaryFunction吗?

谢谢!


4
在分类中,您可以在trainControl(..., classProbs = TRUE, summaryFunction = twoClassSummary)内使用summaryFunction twoClassSummary作为摘要函数。然后,在train(..., metric = "Sens")内使用指标Sens - Lluís Ramon
也许有点晚了,但是值得一提的是:using metric="Sens"将选择一个灵敏度最高的模型,但这并不是专门为灵敏度进行“优化”的模型。 - Krrr
2个回答

12
据我所知,在训练中没有直接指定这一点的方法(我自己也搜索了一段时间)。但是,我找到了一个解决办法:可以在数据框中重新排序目标变量的级别。由于训练算法默认将第一个遇到的级别作为正类,因此这可以解决您的问题。只需添加这一行简单的代码即可解决问题:
TARGET <- factor(make.names(c(1,0,1,1,0,0,1,0,1,1,1,0,1,0,0,0,1,0,1,1)))
TARGET <- relevel(TARGET, "X1")

简单而智能的解决方案!!谢谢。 - Mohammad Tanvir Ahamed

0

我编写了一个函数,对我来说更具直观意义,即正类是第二级(levels(TARGET)[2]的结果),因此用于计算灵敏度。

mySummary <- function(data, lev = NULL, model = NULL){

  lvls <- levels(data$obs)

  if (length(lvls) > 2) 
    stop(paste("Your outcome has", length(lvls), "levels. The twoClassSummary() function isn't appropriate."))

  caret:::requireNamespaceQuietStop("ModelMetrics")

  if (!all(levels(data[, "pred"]) == lvls)) 
    stop("levels of observed and predicted data do not match")

  data$y = as.numeric(data$obs == lvls[2])

  rocAUC <- ModelMetrics::auc(ifelse(data$obs == lvls[1], 
                                     0, 
                                     1), 
                              data[, lvls[2]])
  out <- c(rocAUC, 
           sensitivity(data[, "pred"], data[, "obs"], lvls[2]), 
           specificity(data[, "pred"], data[, "obs"], lvls[1]))

  names(out) <- c("ROC", "Sens", "Spec")

  out

} 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接