使用R语言pROC包基于Youden指数计算ROC曲线截断值时结果异常的技术咨询
R语言pROC包基于Youden指数计算ROC曲线截断值时结果异常的技术咨询
嘿,我看了你的问题和代码,马上就发现了问题的核心——你混淆了ROC分析的输入变量类型,导致预期和结果不匹配。咱们一步步理清楚:
你的错误根源
你当前的ROC分析是用logistic回归输出的预测概率来做的,而不是直接用ndka这个原始的预测变量。当你把ndka乘以10得到ndka10后,logistic回归的系数会自动缩小10倍(因为模型要保持预测效果一致),最终计算出的预测概率和原来几乎完全相同。这就导致ROC曲线的最佳截断值(是一个概率值,比如0.7)自然不会按10倍变化,完全不符合你对原始变量阈值的预期。
而你真正要找的是原始ndka变量的MCID截断值,所以得换个正确的姿势来做ROC分析。
修正后的代码(直接用原始变量做ROC)
这才是能得到你预期结果的正确方式——直接用ndka或ndka10作为ROC的预测变量,而不是用logistic回归的预测概率:
install.packages("pROC") library(pROC) # 加载内置数据集 df <- aSAH # 生成放大10倍的ndka变量 df$ndka10 <- 10 * df$ndka # 方法1:用原始ndka构建ROC,计算Youden指数最佳截断值 roc_ndka <- roc(df$outcome, df$ndka, direction = "<") # 输出所有最佳截断相关指标 coords(roc_ndka, "best", ret = "all") # 方法2:用放大10倍的ndka10构建ROC roc_ndka10 <- roc(df$outcome, df$ndka10, direction = "<") coords(roc_ndka10, "best", ret = "all")
跑这段代码你会发现,ndka10的最佳截断值正好是ndka的10倍,完全符合你的预期。
如果你一定要用logistic回归的结果怎么办?
如果因为某些原因,你必须基于logistic回归的预测概率来反推原始变量的阈值,那可以通过回归系数反向计算:
# 用ndka构建logistic模型 model <- glm(outcome ~ ndka, data = df, family = binomial) # 基于预测概率做ROC roc_out <- roc(df$outcome, predict(model, type = "response"), direction = "<") best_coords <- coords(roc_out, "best", ret = "all") # 把概率截断值转换为logit值 logit_cutoff <- log(best_coords$threshold / (1 - best_coords$threshold)) # 反推原始ndka的截断值 ndka_cutoff <- (logit_cutoff - coef(model)[1]) / coef(model)[2] cat("ndka的原始截断值:", ndka_cutoff, "\n") # 对ndka10重复操作 model2 <- glm(outcome ~ ndka10, data = df, family = binomial) roc_out2 <- roc(df$outcome, predict(model2, type = "response"), direction = "<") best_coords2 <- coords(roc_out2, "best", ret = "all") logit_cutoff2 <- log(best_coords2$threshold / (1 - best_coords2$threshold)) ndka10_cutoff <- (logit_cutoff2 - coef(model2)[1]) / coef(model2)[2] cat("ndka10的截断值:", ndka10_cutoff, "\n")
这段代码会帮你从预测概率的截断值,反推出原始变量的阈值,结果同样会满足10倍的对应关系。
最后总结一下
你要的是原始预测变量的MCID,就直接用该变量做ROC分析,别绕到预测概率的ROC上。后者的截断值是概率值,和原始变量的缩放没有直接的倍数关系,这就是你之前代码出问题的核心原因。
内容来源于stack exchange




