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
时,我得到 fpr
、fnr
和 thresholds
。
我有 2 个问题,可能有点理论性,但请向我解释一下:
这些阈值是实际计算出来的吗?我已经手动计算了fpr
和fnr
,但是这些阈值=上面的分数吗?
如何在 R
中生成相同的 fpr
、fnr
和 thresholds
?
阈值通常对应于使 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 预测的测试集。
我在 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
,但是这些阈值=上面的分数吗?如何在
R
中生成相同的fpr
、fnr
和thresholds
?
阈值通常对应于使 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 预测的测试集。