2.10.1 ROC曲线与AUC

更新日期

2026年11月9日

功能说明

用已准备的 huyiba_rawdata_validation 计算经验 ROC 曲线和 AUC。每行有同一条评价记录的二分类真实结局和有限数值评分,两个类别均出现,无缺失。用 outcome_var、score_var 指定列,并用 positive_level 指定阳性;评分须越高越倾向阳性。

huyiba_result 返回评价记录数、阳性数、AUC 和各阈值坐标,并在当前图形设备显示 ROC。原理及结果解释见2.10.1 ROC曲线与AUC。

核心R包

包名 主要用途 实际验证版本
base(R 基础包) 同分处理、累积计数及面积计算 4.5.2(随 R 4.5.2)
graphics(R 基础包) 绘制 ROC 曲线和参考线 4.5.2(随 R 4.5.2)

无需安装额外分析包。

代码

准备符合要求的输入后,修改开头的配置。下载同一份 R 源码。

# 评价已取得的二分类评分;huyiba_rawdata_validation 每行有真实结局与对应分数。
outcome_var <- "outcome"
score_var <- "score"
positive_level <- "yes"
negative_level <- "no"
# 评分必须越高越倾向阳性;若评分定义相反,按来源预先调整方向。

# 不丢弃行:分数与真实结局须来自同一批评价记录,并已逐行对齐。
input_columns <- c(outcome_var, score_var)
if (anyDuplicated(input_columns) || !all(input_columns %in% names(huyiba_rawdata_validation))) {
  stop("真实结局列和评分列必须存在且不同。")
}
huyiba_analysis_data <- huyiba_rawdata_validation[input_columns]
outcomes <- as.character(huyiba_analysis_data[[outcome_var]])
scores <- huyiba_analysis_data[[score_var]]
if (anyNA(outcomes) || identical(positive_level, negative_level) ||
    !setequal(outcomes, c(negative_level, positive_level)) ||
    !is.numeric(scores) || !is.null(dim(scores)) || any(!is.finite(scores))) {
  stop("评价数据须同时含两个指定类别,且每行有一个有限数值评分。")
}

# 从高分向低分扫过阈值;同分记录一起进入,判阳性规则为 score >= threshold。
score_order <- order(scores, decreasing = TRUE)
sorted_scores <- scores[score_order]
positive <- outcomes[score_order] == positive_level
last_at_score <- !duplicated(sorted_scores, fromLast = TRUE)
curve <- data.frame(
  threshold = c(Inf, sorted_scores[last_at_score]),
  false_positive_rate = c(0, cumsum(!positive)[last_at_score] / sum(!positive)),
  sensitivity = c(0, cumsum(positive)[last_at_score] / sum(positive))
)

# 在假阳性率尺度上做梯形积分;同分的阳性/阴性配对各计半次。
left <- seq_len(nrow(curve) - 1L)
auc <- sum(diff(curve$false_positive_rate) *
  (curve$sensitivity[left] + curve$sensitivity[left + 1L]) / 2)
huyiba_result <- list(
  n = length(scores), positive_n = sum(positive), auc = auc, curve = curve
)
print(c(n = huyiba_result$n, positive = huyiba_result$positive_n, AUC = auc))

graphics::plot(
  curve$false_positive_rate, curve$sensitivity, type = "l",
  xlim = c(0, 1), ylim = c(0, 1), las = 1,
  xlab = "False positive rate (1 - specificity)", ylab = "Sensitivity",
  col = "#176181", lwd = 2
)
graphics::segments(0, 0, 1, 1, lty = 2, col = "gray55", lwd = 1.4)

注意事项

  • 评分必须来自已经固定的模型或检验;在评价记录上不要重新拟合或按 AUC 高低反转方向。
  • 模板只要求有序评分,无须是概率。无实际区分的等分数返回 AUC 0.5;只剩一个结局类别则无法计算。
  • AUC 用于评价区分度;校准、阈值选择、置信区间及外部验证需另做。