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

Python中如何基于5组ROC值的均值与标准差绘制ROC曲线

Python绘制5组结果带误差带ROC曲线实现方案

要画出和参考效果一致的带均值、标准差区间的ROC曲线,不能只存每组的最终AUC值,需要保留每组ROC的FPR/TPR点集,通过插值对齐坐标轴后再计算统计量,具体实现如下:

依赖库准备

先导入需要的工具包:

import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import roc_curve, auc
from scipy import interp

核心实现逻辑

  • 统一插值基准:因为每组ROC的FPR(假正率)采样点不完全一致,无法直接计算均值,需要先生成0到1区间等距分布的固定FPR网格,把所有组的TPR(真正率)插值到这套统一坐标上。
  • 逐组计算指标:遍历5组数据,分别计算每组的FPR、TPR、AUC值,将插值后的TPR结果存入列表。
  • 计算统计量:基于对齐后的TPR数组,计算所有组的TPR均值、TPR标准差,同时计算平均AUC和AUC的标准差。
  • 分层绘图:先画低透明度的单组ROC作为背景,再画对角随机参考线、平均ROC曲线,最后填充±1标准差的误差区间,添加图例和标注即可匹配参考图效果。

完整可运行代码

# 配置绘图中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# 初始化固定FPR插值轴,取100个等距点
mean_fpr = np.linspace(0, 1, 100)
tpr_collect = []
auc_collect = []

# --------------------
# 替换为你自己的5组数据:格式为5个元组,每个元组存(该组真实标签, 模型预测正类概率)
# 以下是5折交叉验证的模拟数据,实际使用时删除这部分替换成自己的真实数据即可
from sklearn.datasets import make_classification
from sklearn.model_selection import KFold
from sklearn.linear_model import LogisticRegression
X, y = make_classification(n_samples=1000, n_features=20, random_state=42)
kf = KFold(n_splits=5, shuffle=True, random_state=42)
cv_dataset = []
for train_idx, test_idx in kf.split(X):
    clf = LogisticRegression(max_iter=1000).fit(X[train_idx], y[train_idx])
    pred_prob = clf.predict_proba(X[test_idx])[:, 1]
    cv_dataset.append((y[test_idx], pred_prob))
# 模拟数据部分结束
# --------------------

plt.figure(figsize=(8, 8), dpi=100)
# 逐组绘制单折ROC
for fold_id, (y_true, y_score) in enumerate(cv_dataset):
    fpr, tpr, _ = roc_curve(y_true, y_score)
    fold_auc = auc(fpr, tpr)
    auc_collect.append(fold_auc)
    # TPR插值对齐
    tpr_interp = interp(mean_fpr, fpr, tpr)
    tpr_interp[0] = 0.0
    tpr_collect.append(tpr_interp)
    # 单折曲线用低透明度细线
    plt.plot(fpr, tpr, lw=1, alpha=0.3, label=f'第{fold_id+1}组 ROC (AUC={fold_auc:.2f})')

# 计算均值、标准差
mean_tpr = np.mean(tpr_collect, axis=0)
mean_tpr[-1] = 1.0
mean_auc_val = auc(mean_fpr, mean_tpr)
std_tpr = np.std(tpr_collect, axis=0)
tpr_upper_bound = np.minimum(mean_tpr + std_tpr, 1)
tpr_lower_bound = np.maximum(mean_tpr - std_tpr, 0)

# 绘制参考线、平均曲线、误差带
plt.plot([0, 1], [0, 1], linestyle='--', lw=2, color='gray', label='随机猜测基准', alpha=0.8)
plt.plot(mean_fpr, mean_tpr, color='tab:blue', lw=2, 
         label=f'平均ROC (AUC={mean_auc_val:.2f} ± {np.std(auc_collect):.2f})')
plt.fill_between(mean_fpr, tpr_lower_bound, tpr_upper_bound, 
                 color='tab:blue', alpha=0.2, label='±1 标准差区间')

# 图表样式调整
plt.xlim([-0.02, 1.02])
plt.ylim([-0.02, 1.02])
plt.xlabel('假正率 (FPR)', fontsize=12)
plt.ylabel('真正率 (TPR)', fontsize=12)
plt.title('5组结果ROC曲线', fontsize=14)
plt.legend(loc='lower right', fontsize=10)
plt.show()

注意事项

  • 禁止直接对5组单独计算的AUC值取平均作为平均ROC的AUC,必须先对齐TPR/FPR坐标后再计算平均曲线的AUC,结果才符合统计规范。
  • 填充的误差带来自每个FPR点位上TPR的标准差,图例中标注的±值是AUC的标准差,二者不要混淆。
  • 单组ROC设置30%左右的透明度,既可以展示所有组的波动情况,又不会干扰平均曲线的展示,和参考图视觉效果一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 03:12:19