使用预测概率的插入符包中的自定义性能函数

Geo*_*ery 3 r machine-learning r-caret

这篇 SO 文章是关于在包中使用自定义性能测量函数的caret。您想要找到最佳的预测模型,因此您构建了多个预测模型,并通过计算通过比较观察值和预测值得出的单个指标来比较它们。有默认函数来计算此指标,但您也可以定义自己的指标函数。此自定义函数必须将观测值和预测值作为输入。

在分类问题(假设只有两个类别)中,预测值是01。然而,我需要评估的也是模型中计算的概率。有什么办法可以实现这一点吗?

原因是,在某些应用程序中,您需要知道1预测的概率实际上是 99% 还是 51%,而不仅仅是预测是 1 还是 0。

有人可以帮忙吗?


编辑 好,让我尝试更好地解释一下。在 5.5.5(替代性能指标)下的包的文档中,caret有一个描述如何使用您自己的自定义性能函数,如下所示

fitControl <- trainControl(method = "repeatedcv",
                           number = 10,
                           repeats = 10,
                           ## Estimate class probabilities
                           classProbs = TRUE,
                           ## Evaluate performance using 
                           ## the following function
                           summaryFunction = twoClassSummary)
Run Code Online (Sandbox Code Playgroud)

twoClassSummary是本例中的自定义性能函数。此处提供的函数需要将带有obs和 的数据帧或矩阵作为输入pred。这就是要点 - 我想使用一个不采用观察和预测的函数,而是采用观察和预测的概率


还有一件事:

也欢迎其他软件包的解决方案。我唯一不寻找的是“这就是你编写自己的交叉验证函数的方式”。

mis*_*use 5

classProbs = TRUE当您在 中指定时,Caret 确实支持将类概率传递给自定义汇总函数trainControl。在这种情况下,data创建自定义汇总函数时的参数将具有额外的两列,名为类,其中包含每个类的概率。这些类的名称将位于参数中,lev该参数是长度为 2 的向量。

参见示例:

library(caret)
library(mlbench)
data(Sonar)
Run Code Online (Sandbox Code Playgroud)

自定义总结LogLoss:

LogLoss <- function (data, lev = NULL, model = NULL){ 
  obs <- data[, "obs"] #truth
  cls <- levels(obs) #find class names
  probs <- data[, cls[2]] #use second class name to extract probs for 2nd clas
  probs <- pmax(pmin(as.numeric(probs), 1 - 1e-15), 1e-15) #bound probability, this line and bellow is just logloss calculation, irrelevant for your question 
  logPreds <- log(probs)        
  log1Preds <- log(1 - probs)
  real <- (as.numeric(data$obs) - 1)
  out <- c(mean(real * logPreds + (1 - real) * log1Preds)) * -1
  names(out) <- c("LogLoss") #important since this is specified in call to train. Output can be a named vector of multiple values. 
  out
}

fitControl <- trainControl(method = "cv",
                           number = 5,
                           classProbs = TRUE,
                           summaryFunction = LogLoss)


fit <-  train(Class ~.,
             data = Sonar,
             method = "rpart", 
             metric = "LogLoss" ,
             tuneLength = 5,
             trControl = fitControl,
             maximize = FALSE) #important, depending on calculated performance measure

fit
#output
CART 

208 samples
 60 predictor
  2 classes: 'M', 'R' 

No pre-processing
Resampling: Cross-Validated (5 fold) 
Summary of sample sizes: 166, 166, 166, 167, 167 
Resampling results across tuning parameters:

  cp          LogLoss  
  0.00000000  1.1220902
  0.01030928  1.1220902
  0.05154639  1.1017268
  0.06701031  1.0694052
  0.48453608  0.6405134

LogLoss was used to select the optimal model using the smallest value.
The final value used for the model was cp = 0.4845361.
Run Code Online (Sandbox Code Playgroud)

或者使用lev包含类级别的参数并定义一些错误检查

LogLoss <- function (data, lev = NULL, model = NULL){ 
 if (length(lev) > 2) {
        stop(paste("Your outcome has", length(lev), "levels. The LogLoss() function isn't appropriate."))
    }
  obs <- data[, "obs"] #truth
  probs <- data[, lev[2]] #use second class name
  probs <- pmax(pmin(as.numeric(probs), 1 - 1e-15), 1e-15) #bound probability
  logPreds <- log(probs)        
  log1Preds <- log(1 - probs)
  real <- (as.numeric(data$obs) - 1)
  out <- c(mean(real * logPreds + (1 - real) * log1Preds)) * -1
  names(out) <- c("LogLoss")
  out
}
Run Code Online (Sandbox Code Playgroud)

查看插入符书的这一部分:https ://topepo.github.io/caret/model-training-and-tuning.html#metrics

获取更多信息。如果您打算使用插入符号,即使您不这样做,这本书也值得一读。