【问题标题】:Performance testing with custom summaryFunction使用自定义 summaryFunction 进行性能测试
【发布时间】:2020-07-26 08:50:04
【问题描述】:

我正在使用插入符号中的自定义 summaryFunction 调整参数。

我原本以为如果我设置K折交叉验证,输入数据有N个点,性能会用N/K个数据点来衡量。

但是,显然这似乎不正确,因为当我使用 browser() 提取 data$pred 时,它是传递给汇总函数的数据,它只有 10 个数据。 由于输入(df)有超过 500 个数据点,这个数字比我预期的要小。

为什么它只有 10 个数据?有什么办法可以增加这个吗?(=使用更多大数据点进行性能测试)

需要任何帮助。谢谢。

sigma.list <- seq(1, 5, 1)
c.list <- seq(1, 10, 1)
met <- "FValue"

#define evaluation function
eval <- function(data, lev = NULL, model = NULL){
  mat <- table(data$pred, data$obs)
  pre <- mat[1,1]/sum(mat[1,]) #precision
  rec <- mat[1,1]/sum(mat[,1]) #recall
  res <- c("Precision"=pre, "Recall"=rec, "FValue"=2*pre*rec/(pre+rec))
  browser()
  res
}
#define train control
tc <-  trainControl(method = "cv",
                    number = 5,
                    summaryFunction = eval,
                    classProbs = TRUE,
                    )

#tune with caret
svm.tune <- train(Flag~.,
                   data = df,
                   method = "svmRadial",
                   tuneGrid = expand.grid(C=c.list, sigma=sigma.list),
                   trControl = tc,
                   metric = met
                   )

【问题讨论】:

  • 我只是观察到了同样的情况。看来caretsummaryFunction 的第一次调用(你称它为eval)通过了data.frame,第一次只有十个样本。如果您继续调试,您将看到下一个调用具有正确数量的样本。我不确定为什么会发生这种情况,不幸的是必须查看caret 源代码。如果我弄明白了会更新你。

标签: r performance-testing cross-validation r-caret


【解决方案1】:

跟踪此问题后,这似乎是正常的caret 行为。

我认为caret 本质上是通过向它传递假数据(长度为 10)来验证您的 summaryFunction 是否正常工作。 caret 内部的函数是 evalSummaryFunction

我不太确定我在 RStudio 的调试器中在做什么,但 train.default 中的这段代码:

  testSummary <- evalSummaryFunction(y, wts = weights, 
    ctrl = trControl, lev = classLevels, metric = metric, 
    method = method)
  perfNames <- names(testSummary)

调用evalSummaryFunction,看起来像:

function (y, wts = NULL, perf = NULL, ctrl, lev, metric, method) 
{
  n <- if (class(y)[1] == "Surv") 
    nrow(y)
  else length(y)
  if (class(y)[1] != "Surv") {
    if (is.factor(y)) {
      values <- rep_len(levels(y), min(10, n))
      pred_samp <- factor(sample(values), levels = lev)
      obs_samp <- factor(sample(values), levels = lev)
    }
    else {
      pred_samp <- sample(y, min(10, n))
      obs_samp <- sample(y, min(10, n))
    }
  }
  else {
    pred_samp <- y[sample(1:n, min(10, n)), "time"]
    obs_samp <- y[sample(1:n, min(10, n)), ]
  }
  testOutput <- data.frame(pred = pred_samp, obs = obs_samp)
  if (!is.null(perf)) {
    if (is.vector(perf)) 
      stop("`perf` should be a data frame", call. = FALSE)
    perf <- perf[sample(1:nrow(perf), nrow(testOutput)), 
      , drop = FALSE]
    testOutput <- cbind(testOutput, perf)
  }
  if (ctrl$classProbs) {
    for (i in seq(along = lev)) testOutput[, lev[i]] <- runif(nrow(testOutput))
    testOutput[, lev] <- t(apply(testOutput[, lev], 1, function(x) x/sum(x)))
  }
  else {
    if (metric == "ROC" & !ctrl$classProbs) 
      stop("train()'s use of ROC codes requires class probabilities. See the classProbs option of trainControl()")
  }
  if (!is.null(wts)) 
    testOutput$weights <- sample(wts, min(10, length(wts)))
  testOutput$rowIndex <- sample(1:n, size = nrow(testOutput))
  ctrl$summaryFunction(testOutput, lev, method)
}

看来 10 是 caret 传递给您的摘要函数以评估它的假数据的长度(确保它正常工作?)。

如果有人可以更好地验证/解释 caret 实际在做什么,请发帖。

【讨论】:

  • 非常感谢您的调试。我真的很感激,因为这超出了我的能力。仍然不确定为什么是“10”,但希望将来有人能回答这个问题。再次感谢您的分析。
  • @MPO 我相信它是 10,因为人类通常有十根手指。换句话说,这只是对您的自定义summaryFunction 的任意测试,让您知道它是否有任何问题(而不是稍后收到一些神秘的错误消息)。
  • 感谢您的跟进。我知道数字 10 没有任何意义。我很抱歉问这个问题,因为这是一个非常基本的问题,但是如何使用我的自定义 eval 正确训练模型。功能?因为“data$pred”只有 10 个数据,我假设该模型是在我的代码中使用假数据进行训练的。 (也就是说模型是垃圾?)提前谢谢你的好意。
猜你喜欢
  • 2014-06-27
  • 2013-05-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-18
  • 2011-11-01
  • 1970-01-01
相关资源
最近更新 更多