You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在同一张图中绘制两个XGBoost模型的精美ROC曲线

问题解答

1. 获取ROC曲线所需的truth和Prediction Scores

  • Truth(真实标签):
    是对应数据集的目标特征标签,优先使用测试集的标签——用训练集标签绘制的ROC曲线会高估模型性能,无法反映泛化能力;如果只是观察训练集拟合效果,才用训练集的目标标签。
  • Prediction Scores(预测分数/概率):
    XGBoost模型需要输出连续的预测值(不是类别标签),获取方式分两种情况:
    • 原生xgboost包训练的模型:
      # 假设test_data是测试集特征,test_labels是测试集真实标签
      # 输出logit分数,可转换为概率
      scores1 <- predict(model1, newdata = xgb.DMatrix(test_data))
      scores1_prob <- 1 / (1 + exp(-scores1)) # 转换为正类概率
      
    • caret/mlr等封装包训练的模型:
      # 直接获取正类概率(第二列是类别1的概率)
      scores1 <- predict(model1, newdata = test_df, type = "prob")[,2]
      truth1 <- test_df$target_column # 测试集真实标签
      

2. 代码修正与完整实现

现有代码的错误点

  • data.frame = (fpr = ...)语法错误,多了冗余的等号,正确写法是data.frame(fpr = ...)
  • 使用geom_smooth会对ROC曲线做平滑拟合,导致曲线失真,ROC曲线应该用折线绘制
  • 第一个annotate("text")缺失y参数,第二个标注的字符串未闭合
  • 缺少ROC图必备的随机猜测基准线(对角线)

修正后的完整代码

# 加载所需包
library(pROC)
library(ggplot2)
library(tibble)

# ----------------------
# 第一步:获取truth和scores
# ----------------------
# 示例:假设用caret训练模型,test_df是测试集,target列是y
truth1 <- test_df$y
scores1 <- predict(model1, newdata = test_df, type = "prob")[,2]
truth2 <- test_df$y
scores2 <- predict(model2, newdata = test_df, type = "prob")[,2]

# ----------------------
# 第二步:计算ROC对象
# ----------------------
roc1 <- roc(truth1, scores1)
roc2 <- roc(truth2, scores2)

# ----------------------
# 第三步:转换为绘图用数据框
# ----------------------
D1 <- data.frame(fpr = 1 - roc1$specificities, tpr = roc1$sensitivities)
D2 <- data.frame(fpr = 1 - roc2$specificities, tpr = roc2$sensitivities)

# 箭头标注数据
arrows_df <- tibble(x1 = c(0.5, 0.13), 
                    x2 = c(0.32, 0.2), 
                    y1 = c(0.52, 0.83), 
                    y2 = c(0.7, 0.7))

# ----------------------
# 第四步:绘制ROC曲线
# ----------------------
ggplot() +
  # 添加随机猜测基准线(虚线)
  geom_abline(intercept = 0, slope = 1, color = "gray50", linetype = "dashed") +
  # 绘制两个模型的ROC折线
  geom_line(data = D1, aes(x = fpr, y = tpr), color = "#1f77b4", linewidth = 1) +
  geom_line(data = D2, aes(x = fpr, y = tpr), color = "#ff4b5c", linewidth = 1) +
  # 绘制标注箭头
  geom_segment(data = arrows_df, aes(x = x1, y = y1, xend = x2, yend = y2),
               arrow = arrow(length = unit(0.2, "cm")), color = "black") +
  # 添加AUC分数标注
  annotate("text", x = 0.5, y = 0.475, label = paste0("Model 1 AUC: ", round(roc1$auc, 2))) +
  annotate("text", x = 0.13, y = 0.9, label = paste0("Model 2 AUC: ", round(roc2$auc, 2))) +
  # 图表标签与主题设置
  labs(x = "False Positive Rate (FPR)", 
       y = "True Positive Rate (TPR)", 
       title = "ROC Curves: Model 1 vs Model 2") +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5, size = 14, face = "bold"),
        axis.title = element_text(size = 12),
        legend.position = "bottom")

代码说明

  • 用geom_line替代geom_smooth,保证ROC曲线是真实的阶梯状(如果需要平滑效果,可保留geom_smooth并设置method = "loess",但不推荐)
  • 添加了灰色虚线的基准线,用于对比模型与随机猜测的性能
  • 标注中加入了AUC分数,直观展示模型性能
  • 使用theme_minimal优化图表样式,提升美观度

内容的提问来源于stack exchange,提问作者Kev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 09:30:57