我在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
时,我得到fpr
,fnr
和thresholds
。
我有2个问题,也许有点理论,但请向我解释一下:
这些阈值是否实际计算?我手动计算fpr
和fnr
,但这些阈值是否高于上述分数?
如何在fpr
中生成相同的fnr
,thresholds
和R
?
答案 0 :(得分:2)
阈值通常对应于最大化tpr + tnr(灵敏度+特异性)的值,这称为Youden J指数(tpr + tnr - 1),但也有其他几个名称。
以Sonar数据集为例:
library(mlbench)
library(xgboost)
library(caret)
library(pROC)
data(Sonar)
让模型适用于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,]
话虽如此,通常在考虑财务数据时,不仅仅是阶级是否有兴趣,而且还有与错误预测相关的成本,这些假预测通常与假阴性和误报相同。所以这些模型适合使用成本敏感的分类。 More on the mater。 另一方面,在确定阈值时,您应该在交叉验证的数据上或在专门为该任务指定的验证集上执行此操作。如果你使用它一个测试集,不可避免地导致过度乐观的预测。