画交叉验证的ROC曲线,多个样本不同的ROC重叠。

本文介绍了一种在深度学习中通过留一法进行10折交叉验证时,如何计算并展示平均ROC曲线及置信区间的技巧。作者使用插值方法处理不同样本量的ROC曲线,确保了可视化结果的准确性和一致性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近在画交叉验证的ROC曲线。由于我采用的是留一法来做10折交叉,这就导致我每一折的样本数量是不固定的,但我又想画一个平均的校验验证性能曲线,并且把置信区间也画出来,找了很久资料,我画了一个这样的。先看效果图,如下图:在这里插入图片描述
中间蓝色的是平均的ROC,周围蓝色的带是所有的交叉验证触及的最大范围。因为交叉验证需要多次抽样,但我用的是深度学习,很难做到抽样,所以就用最大范围代替置信区间。具体做法如下:

from my_utils.utils import *
from sklearn.metrics import auc, plot_roc_curve, roc_curve
import my_utils.file_util as fu
import matplotlib.pyplot as plt
class_type = '1p19q'
#图表的保存路径
save_path = ''
#存放所有交叉验证的预测结果和label的文件路径
record_dir  = ''
#find_file是我自己写的寻找路径下所有best-auc.csv文件的函数,用的时候可以替换成自己的
#返回的是所有csv文件的绝对路径。文件格式是第一和第二列是预测值,第三列label。
#因为我用的是one hot做二分类,所以有两个值
flods_dir = find_file(record_dir, 2,1, suffix='best_auc.csv')
pre_record = []
#获取所有交叉验证的预测值和label
for record_file in flods_dir:
    temp = fu.csv_reader(record_file)
    temp_fold_record = []
    #因为是二分类,所有只取第一个预测值,第二个不要
    temp_fold_record.append([i[0] for i in temp])
    #取label值
    temp_fold_record.append([i[2] for i in temp])
    pre_record.append(temp_fold_record)

roc_record, value, fpr, tpr = [], [], [], []

for record in pre_record:
    label = np.array([int(i) for i in record[1]]).squeeze()
    pred = np.array([float(i) for i in record[0]]).squeeze()
    #计算roc曲线
    t_fpr, t_tpr, thre = roc_curve(label, 1-pred)
    #计算AUC
    auc_score = auc(t_fpr, t_tpr)
    fpr.append([float(i) for i in t_fpr])
    value.extend([float(i) for i in t_fpr])
    tpr.append([float(i) for i in t_tpr])

mean_fpr, min_fpr, max_fpr = [],[],[]
mean_tpr, min_tpr, max_tpr= [],[],[]
#这个是为了对曲线进行插值,因为每个曲线的样本不一样,所以获取到的fpr和tpr也不一样长度,
#所以需要进行插值
#插值的原理是,获取所有fpr的值,然后将每个交叉验证的roc都插值成和fpr的值一样多的长度。
#插值并不会改变每个roc曲线的形状,这个可以放心使用
unique = np.unique(np.array(value).flatten())
#对fpr和tpr进行插值
for l in range(len(fpr)):
    tpr[l] = np.interp(unique, fpr[l], tpr[l], 0, 1)
    fpr[l] = np.interp(unique, fpr[l], fpr[l], 0, 1)
    #将每个交叉验证的ROC都画出来
    plt.plot(fpr[l], tpr[l])

fpr = np.array(fpr)
tpr = np.array(tpr)
#求fpr和tpr的极大极小,获取每个实验所能触及的最大指标范围
min_fpr = np.min(fpr, axis=0)
max_fpr = np.max(fpr, axis=0)
min_tpr = np.min(tpr, axis=0)
max_tpr = np.max(tpr, axis=0)
#获取均值,为了得到交叉验证的平均曲线
mean_tpr = np.mean(tpr, axis=0)
mean_fpr = np.mean(fpr, axis=0)
mean_tpr[0] = 0

plt.figure(dpi=300)
plt.title(class_type)
plt.style.use('seaborn')
plt.xlabel('1-Specificity')
plt.ylabel('Sencitivity')
#画平均曲线
p1 = plt.plot(mean_fpr, mean_tpr, marker='.', 
        linestyle='--',c='b', linewidth=1,
         alpha=0.65, label='20X')#markeredgecolor='b',

plt.legend(loc='lower right')
#将极大极小值的范围填充淡蓝色
p2 = plt.fill_between(min_fpr,max_tpr, min_tpr,color='blue', alpha=0.08)
#展示图象
plt.show()

下面附上每个交叉验证的图像来验证范围画的对不对。
在这里插入图片描述
再对比我们画的在这里插入图片描述
可以看到啊,我们画的范围与所有ROC的曲线的范围是吻合的,平均曲线也像模像样。

交叉验证是一种模型评估方法,它可以减少模型评估的方差。在Python中,使用交叉验证ROC曲线结合可以评估模型在不同数据子集上的表现,ROC曲线(接收者操作特征曲线)是一种评估分类器性能的工具,它通过绘制真正率(TPR)与假正率(FPR)之间的关系来表示模型的性能。 在Python中实现交叉验证ROC曲线的典型步骤如下: 1. 准备数据集:将数据集分成特征和标签两部分,并根据需要对数据进行标准化或其他预处理。 2. 划分数据集:使用交叉验证的方法将数据集划分成多个子集。常见的交叉验证方法包括K交叉验证(K-Fold Cross Validation)和留一交叉验证(Leave-One-Out Cross Validation)。 3. 训练模型:对于每一个子集,使用一部分数据作为训练集,另一部分作为验证集,训练分类器。 4. 计算ROC曲线:在每个验证集上评估模型的预测性能,计算真正率和假正率,并绘制ROC曲线。 5. 分析结果:结合所有子集的结果,评估模型的平均性能和稳定性。 下面是一个使用Python的scikit-learn库实现上述步骤的简化示例代码: ```python from sklearn.datasets import make_classification from sklearn.model_selection import cross_val_curve from sklearn.linear_model import LogisticRegression from sklearn.metrics import roc_curve, auc import matplotlib.pyplot as plt # 生成模拟数据集 X, y = make_classification(n_samples=1000, n_features=20, n_classes=2, random_state=42) # 创建模型 model = LogisticRegression() # 计算不同决策阈值下的ROC曲线 tprs = [] aucs = [] mean_fpr = np.linspace(0, 1, 100) # 10交叉验证计算ROC曲线和AUC for train, test in KFold(n_splits=10): probas_ = model.fit(X[train], y[train]).predict_proba(X[test]) # 计算当前叠的ROC曲线和AUC fpr, tpr, thresholds = roc_curve(y[test], probas_[:, 1]) tprs.append(np.interp(mean_fpr, fpr, tpr)) tprs[-1][0] = 0.0 roc_auc = auc(fpr, tpr) aucs.append(roc_auc) # 计算平均ROC曲线 mean_tpr = np.mean(tprs, axis=0) mean_tpr[-1] = 1.0 mean_auc = auc(mean_fpr, mean_tpr) # 绘制平均ROC曲线 plt.plot(mean_fpr, mean_tpr, color='b', label=r'Mean ROC (AUC = %0.2f )' % mean_auc, lw=2, alpha=0.8) ```
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值