选择逻辑模型预测的概率阈值以获得一定的特异性
Choosing probability threshold of logistic model predictions to obtain a certain specificity
我有一个逻辑预测模型,它为每个人生成了成为案例的概率。模型 AUC 为 0.95。
有没有办法确定 阈值 的概率,使我的特异性达到 0.9? (或任何其他任意指定的特异性或敏感性水平。)谢谢。
灵敏度和特异性的经验值当然取决于数据集。您可以尝试使用 predict
提取逻辑模型预测的 class 概率并设置不同的阈值以根据特异性对其进行校准,但请记住,为了使您的特异性数据在测试数据上保持准确,比例的 classes 必须类似地分布在训练和测试人群中。在下面的示例中,我创建了一个函数来将训练数据特异性映射到模拟数据集的逻辑模型概率响应阈值。
set.seed(100)
x = rnorm(1000)
y = sapply(x, function(zeta) rbinom(1, 1, plogis(zeta)))
data <- data.frame(x = x, y = y)
logistic_model <- glm(data = data, formula = y ~ 0 + x, family = "binomial")
summary(logistic_model)
# Call:
# glm(formula = y ~ 0 + x, family = "binomial", data = data)
#
# Deviance Residuals:
# Min 1Q Median 3Q Max
# -2.4626 -0.9187 0.5383 1.0284 2.3236
#
# Coefficients:
# Estimate Std. Error z value Pr(>|z|)
# x 1.09347 0.08576 12.75 <2e-16 ***
# ---
# Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#
# (Dispersion parameter for binomial family taken to be 1)
#
# Null deviance: 1386.3 on 1000 degrees of freedom
# Residual deviance: 1163.2 on 999 degrees of freedom
# AIC: 1165.2
#
# Number of Fisher Scoring iterations: 4
data$response <- predict(logistic_model, type = "response")
p_vals = seq(0,1,0.001)
specificity <- sapply(p_vals, function(p) sum(data$y == 0 & data$response < p)/sum(data$y == 0))
plot(p_vals, specificity, type = "l")
threshold_by_specificity <- function(spc)
return(p_vals[sum(specificity <= spc)])
threshold_by_specificity(0.1)
##0.13
threshold_by_specificity(0.3)
##0.251
P.S。我很确定 caret
包中有一个函数可以做到这一点,但我找不到它。
P.P.S。顺便说一句,逻辑模型为给定的特征向量指定class的概率分布,而获得灵敏度and/or特异性的理论值将涉及相反的情况,即指定分布的模型给定 class 的特征向量。要从逻辑模型中获得这一点,您需要假设数据的先验分布(或适合它)。如果没有更多详细信息,则不清楚您应该如何去做,或者是否需要这样做。
我有一个逻辑预测模型,它为每个人生成了成为案例的概率。模型 AUC 为 0.95。
有没有办法确定 阈值 的概率,使我的特异性达到 0.9? (或任何其他任意指定的特异性或敏感性水平。)谢谢。
灵敏度和特异性的经验值当然取决于数据集。您可以尝试使用 predict
提取逻辑模型预测的 class 概率并设置不同的阈值以根据特异性对其进行校准,但请记住,为了使您的特异性数据在测试数据上保持准确,比例的 classes 必须类似地分布在训练和测试人群中。在下面的示例中,我创建了一个函数来将训练数据特异性映射到模拟数据集的逻辑模型概率响应阈值。
set.seed(100)
x = rnorm(1000)
y = sapply(x, function(zeta) rbinom(1, 1, plogis(zeta)))
data <- data.frame(x = x, y = y)
logistic_model <- glm(data = data, formula = y ~ 0 + x, family = "binomial")
summary(logistic_model)
# Call:
# glm(formula = y ~ 0 + x, family = "binomial", data = data)
#
# Deviance Residuals:
# Min 1Q Median 3Q Max
# -2.4626 -0.9187 0.5383 1.0284 2.3236
#
# Coefficients:
# Estimate Std. Error z value Pr(>|z|)
# x 1.09347 0.08576 12.75 <2e-16 ***
# ---
# Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#
# (Dispersion parameter for binomial family taken to be 1)
#
# Null deviance: 1386.3 on 1000 degrees of freedom
# Residual deviance: 1163.2 on 999 degrees of freedom
# AIC: 1165.2
#
# Number of Fisher Scoring iterations: 4
data$response <- predict(logistic_model, type = "response")
p_vals = seq(0,1,0.001)
specificity <- sapply(p_vals, function(p) sum(data$y == 0 & data$response < p)/sum(data$y == 0))
plot(p_vals, specificity, type = "l")
threshold_by_specificity <- function(spc)
return(p_vals[sum(specificity <= spc)])
threshold_by_specificity(0.1)
##0.13
threshold_by_specificity(0.3)
##0.251
P.S。我很确定 caret
包中有一个函数可以做到这一点,但我找不到它。
P.P.S。顺便说一句,逻辑模型为给定的特征向量指定class的概率分布,而获得灵敏度and/or特异性的理论值将涉及相反的情况,即指定分布的模型给定 class 的特征向量。要从逻辑模型中获得这一点,您需要假设数据的先验分布(或适合它)。如果没有更多详细信息,则不清楚您应该如何去做,或者是否需要这样做。