Python 和 R 中的 ROC-AUC FPR FNR?

ROC-AUC FPR FNR in Python and R?

我在 R/Python 中有一个数据框对象,看起来像:

df columns:
fraud = [1,1,0,0,0,0,0,0,0,1]
score = [0.84, 1, 1.1, 0.4, 0.6, 0.13, 0.32, 1.4, 0.9, 0.45]

当我在 Python 中使用 roc_curve 时,我得到 fprfnrthresholds

我有 2 个问题,可能有点理论性,但请向我解释一下:

  1. 这些阈值是实际计算出来的吗?我已经手动计算了fprfnr,但是这些阈值=上面的分数吗?

  2. 如何在 R 中生成相同的 fprfnrthresholds

阈值通常对应于使 tpr + tnr(灵敏度 + 特异性)最大化的值,这称为 Youden J 指数 (tpr + tnr - 1),但也有其他几个名称。

以声纳数据集为例:

library(mlbench)
library(xgboost)
library(caret)
library(pROC)
data(Sonar)

让我们对部分声纳数据拟合模型并预测另一部分:

ind <- createDataPartition(Sonar$Class, p = 0.7, list = FALSE)
train <- Sonar[ind,]
test <- Sonar[-ind,]
X = as.matrix(train[, -61])
dtrain = xgb.DMatrix(data = X, label = as.numeric(train$Class)-1)
dtest <- xgb.DMatrix(data = as.matrix(test[, -61]))

在训练数据上拟合模型:

model = xgb.train(data = dtrain, 
                  eval = "auc",
                  verbose = 0,  maximize = TRUE, 
                  params = list(objective = "binary:logistic",
                                eta = 0.1,
                                max_depth = 6,
                                subsample = 0.8,
                                lambda = 0.1 ), 
                  nrounds = 10)

preds <- predict(model, dtest)
true <- as.numeric(test$Class)-1


plot(roc(response = true,
         predictor =  preds,
         levels=c(0, 1)),
     lwd=1.5, print.thres = T, print.auc = T, print.auc.y = 0.5)

因此,如果您将阈值设置为 0.578,您将最大化值 tpr + tnr,图中括号中的值为 tpr 和 tnr。验证:

sensitivity(as.factor(ifelse(preds > 0.578, "1", "0")), as.factor(true))
#output
[1] 0.9090909
specificity(as.factor(ifelse(preds > 0.578, "1", "0")), as.factor(true))\
#output
[1] 0.7586207

您可以在许多可能的阈值上创建预测:

do.call(rbind, lapply((1:1000)/1000, function(x){
  sens <- sensitivity(as.factor(ifelse(preds > x, "1", "0")), as.factor(true))
  spec <- specificity(as.factor(ifelse(preds > x, "1", "0")), as.factor(true))
  data.frame(sens, spec)
})) -> thresh

现在:

thresh[which.max(rowSums(thresh)),]
#output
         sens      spec
560 0.9090909 0.7586207

你也可以看看这个:

thresh[555:600,]

话虽如此,通常在考虑财务数据时,不仅 class 不感兴趣,而且与错误预测相关的成本通常与假阴性和假阳性不同。所以这些模型适合使用 cost-sensitive class化。 More on the mater。 另一方面,在决定阈值时,您应该在交叉验证数据或专门为任务指定的验证集上进行。如果你使用它,那么不可避免地会导致 over-optimistic 预测的测试集。