首页 > 解决方案 > 在 R 中使用交叉验证和调整进行径向 SVM 分类

问题描述

我正在创建径向 SVM 分类模型,我将对其执行 5 倍 CV 并对其进行调整。我在这里看到了其他人是如何做到的,并按照这些说明进行操作。但是,我的代码不想实现我的调整网格。另外,我不明白为什么在显式训练模型时无法获得准确度或 F1 值。

5倍简历

library(caret)
set.seed(500)
ctrl <- trainControl(method = "repeatedcv",
                      number = 5,
                      repeats = 3, 
                      classProb=T,
                      summaryFunction = twoClassSummary
                     )
sigma<-c(2^-15,2^-13,2^-11,2^-9,2^-7,2^-5,2^-3,2^-1,2^1,2^2,2^3)
C<-c(2^-5,2^-3,2^-1,2^1,2^2,2^3,2^5,2^7,2^9,2^11,2^13)
tuninggrid<-data.frame(expand.grid(sigma,C))

mod <- train(x = iris[-5], y=iris$Species,
             method = "svmRadial", 
             trControl = ctrl,
             metric=c('ROC'),
             tunegrid=tuninggrid

结果只是 sigma 保持不变。为什么它不使用我的调整网格?

其次,当我将指标从 调整为 时'ROC''Accuracy'它说准确度不可用。我理解这是因为我的 summaryFunctiontrainControl.如果我删除它,那么我可以获得准确性,但不是 ROC。最终,我想要一个 F1 值,但我找不到这方面的文档。我将如何写一些东西同时给我两个?

最后,来自 的输出train()。要获得权重,它只是使用 mod$finalModel@coef 对吗?

标签: rsvmcross-validationr-caret

解决方案


您的代码中有一些小错误:

  1. 如果你想使用 ROC 下的面积作为度量,你需要twoClassSummary像你一样指定,但你的响应变量也应该是二进制的。例如:
    train(..., y = factor(ifelse(iris$Species=="setosa", "setosa", "other")), ...)
    
  2. 如果您想使用准确度作为指标,请使用defaultSummary而不是twoClassSummary

  3. 如果你View(tuninggrid)会看到它的列名是 Var1 和 Var2,而它们应该是 C 和 sigma。您可以修复其定义:

    tuninggrid <- expand.grid(sigma=sigma,C=C)
    
  4. 调用中有一个错字train(...):正确的参数名称是tuneGrid(R 区分大小写)

修复这些将解决您的问题:View(mod$results)

编辑:如果您想优化精度(在 中计算defaultSummary)但还显示 AUROC(来自twoClassSummary)和/或 F 度量(来自prSummary),您可以定义自己的度量函数,它结合了所有并在 trainControl 中使用它:

combinedSummary <- function(data, lev = NULL, model = NULL) {
  c(
    defaultSummary(data, lev, model),
    twoClassSummary(data, lev, model), 
    prSummary(data, lev, model)
    )
}

推荐阅读