R 插入符号:最大化手动定义的阳性 class 用于训练(class 化)的灵敏度,

R caret: Maximizing sensitivity for manually defined positive class for training (classification),

短版:

有没有办法指示插入符号训练回归模型

  1. 使用用户定义的标签 "positive class label"?
  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)

我想最大化 sensitivity = precision = A / ( A + C )

其中 Event(在图像中)在我的情况下应该是 X1 = action taken。但是插入符 使用 X0 = no action taken.

我可以使用像

这样的positive参数为我的混淆矩阵设置正数class
> confusionMatrix(df$PREDICTION, df$TARGET, positive = "X1")

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

我已经检查过是否有其他指标符合我的需要,但我无法在 documentation 中找到。我必须为 trainControl 实现自己的 summaryFunction 吗?

谢谢!

据我所知,在训练中没有直接的方法来指定它(我自己已经搜索了一段时间)。但是,我找到了一个解决方法:您可以在数据框中重新排序目标变量的级别。由于训练算法默认将第一个遇到的水平作为正class,这解决了你的问题。只需添加这行简单的代码即可达到目的:

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")

我编写了一个对我来说更直观的函数,即正数 class 是第二级(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

}