在Caret中的额外指标 - PPV、敏感度、特异度

8

我在R中使用了caret进行逻辑回归:

  ctrl <- trainControl(method = "repeatedcv", number = 10, repeats = 10, 
                       savePredictions = TRUE)

  mod_fit <- train(Y ~ .,  data=df, method="glm", family="binomial",
                   trControl = ctrl)

  print(mod_fit)

默认输出的度量是准确率和Cohen kappa。我希望能提取匹配度量,比如灵敏度、特异度、阳性预测值等,但我找不到简单的方法。最终模型已经提供,但据文档所述,它是在所有数据上训练的,因此我无法用它来进行新的预测。

混淆矩阵可以计算所有所需的参数,但将其作为汇总函数传递并不起作用:

  ctrl <- trainControl(method = "repeatedcv", number = 10, repeats = 10, 
                       savePredictions = TRUE, summaryFunction = confusionMatrix)

  mod_fit <- train(Y ~ .,  data=df, method="glm", family="binomial",
                   trControl = ctrl)

Error: `data` and `reference` should be factors with the same levels. 
13.
stop("`data` and `reference` should be factors with the same levels.", 
    call. = FALSE) 
12.
confusionMatrix.default(testOutput, lev, method) 
11.
ctrl$summaryFunction(testOutput, lev, method) 

除了准确度和kappa之外,是否有一种方法可以提取这些信息,或者在caret train返回的train_object中找到它们?

谢谢!


你好,Cindy。在使用 caret::train() 之前,你是否将数据拆分为训练组和测试组了呢? - Len Greski
不,我不是。我以为当我指定交叉验证时,插入符号会自动为我完成。这样做不正确吗? - Cindy Almighty
1个回答

14

Caret已经具有摘要函数,可以输出您提到的所有指标:

defaultSummary 输出 准确率和Kappa
twoClassSummary 输出 AUC(ROC曲线下面积-见答案的最后一行),灵敏度和特异度
prSummary 输出 精确度和召回率

为了获得组合指标,您可以编写自己的摘要函数,将这三个摘要函数的结果组合起来。

library(caret)
MySummary  <- function(data, lev = NULL, model = NULL){
  a1 <- defaultSummary(data, lev, model)
  b1 <- twoClassSummary(data, lev, model)
  c1 <- prSummary(data, lev, model)
  out <- c(a1, b1, c1)
  out}

让我们尝试使用Sonar数据集:

library(mlbench)
data("Sonar")

在定义训练控制时,重要的是将classProbs = TRUE设置为真,因为某些度量指标(如ROC和prAUC)无法基于预测的类别进行计算,而是基于预测概率进行计算。

ctrl <- trainControl(method = "repeatedcv",
                     number = 10,
                     savePredictions = TRUE,
                     summaryFunction = MySummary,
                     classProbs = TRUE)

现在选择您喜欢的模型:

mod_fit <- train(Class ~.,
                 data = Sonar,
                 method = "rf",
                 trControl = ctrl)

mod_fit$results
#output
  mtry  Accuracy     Kappa       ROC      Sens      Spec       AUC Precision    Recall         F AccuracySD   KappaSD
1    2 0.8364069 0.6666364 0.9454798 0.9280303 0.7333333 0.8683726 0.8121087 0.9280303 0.8621526 0.10570484 0.2162077
2   31 0.8179870 0.6307880 0.9208081 0.8840909 0.7411111 0.8450612 0.8074942 0.8840909 0.8374326 0.06076222 0.1221844
3   60 0.8034632 0.6017979 0.9049242 0.8659091 0.7311111 0.8332068 0.7966889 0.8659091 0.8229330 0.06795824 0.1369086
       ROCSD     SensSD    SpecSD      AUCSD PrecisionSD   RecallSD        FSD
1 0.04393947 0.05727927 0.1948585 0.03410854  0.12717667 0.05727927 0.08482963
2 0.04995650 0.11053858 0.1398657 0.04694993  0.09075782 0.11053858 0.05772388
3 0.04965178 0.12047598 0.1387580 0.04820979  0.08951728 0.12047598 0.06715206

在这个输出中,ROC实际上是ROC曲线下的面积 - 通常称为AUC,而AUC是所有截断点下的精确度-召回曲线下的面积。


感谢您的出色回答。以下哪些不能基于预测类别而计算,而是基于预测概率? - Cindy Almighty
很高兴能够帮忙。ROC和prAUC需要概率值,因为它们是考虑所有可能的决策阈值而不仅仅是通常使用的0.5标记的度量。因此,在处理不平衡类别时,它们是模型性能更好的度量。 - missuse
完美!在试图修复此问题时我遇到了一个错误:错误:至少有一个类级别不是有效的 R 变量名;当生成类概率时,这会导致错误,因为变量名将被转换为 X0、X1。请使用可以用作有效 R 变量名的 Ffactor 级别(有关帮助,请参见?make.names)。我想这是由于我的大多数变量都使用了“0”和“1”的因子命名。是否有简单的方法解决这个问题?只有 classprobs = True 时才会出现这个问题。 - Cindy Almighty
将类级别名称转换为单词而不是数字进行训练 - 例如使用代替01class <- ifelse(class ==“0”,“zero”,“one”)。之后它应该可以工作。 - missuse
@missuse 抱歉,我第一次误解了示例的使用方式。您的评论帮助我澄清了问题,我现在知道如何在caret中使用MySummary。谢谢,现在它对我有用了! - PleaseHelp
显示剩余2条评论

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