Python中绘制多ROC曲线的均值ROC曲线问题求助
线性核SVM均值ROC曲线未从原点出发的问题修复
问题核心
你遇到的问题根源是每次运行生成的FPR(假阳性率)、TPR(真阳性率)数组长度不一致,直接对不同长度的数组取均值会导致数据对齐错误,无法保证曲线从(0,0)出发。
原疑似问题代码段
fpr_list = [] tpr_list = [] for _ in range(10): svm_model.fit(X_train, y_train) y_score = svm_model.decision_function(X_test) fpr, tpr, _ = roc_curve(y_test, y_score) fpr_list.append(fpr) tpr_list.append(tpr) # 错误操作:直接对不同长度的数组取均值 mean_fpr = np.mean(fpr_list, axis=0) mean_tpr = np.mean(tpr_list, axis=0)
修复方案
解决思路是先生成统一的FPR参考网格,再将每次运行的TPR插值到该网格上,确保所有TPR数组长度一致,同时强制原点(0,0)的存在。
修复后完整代码
import numpy as np from sklearn.svm import SVC from sklearn.metrics import roc_curve, auc import matplotlib.pyplot as plt # 假设训练/测试数据已准备完成:X_train, y_train, X_test, y_test svm_model = SVC(kernel='linear', probability=False) # 生成固定的FPR参考网格(0到1区间,共100个均匀分布点) mean_fpr = np.linspace(0, 1, 100) tprs = [] aucs = [] for _ in range(10): # 训练模型并生成决策分数 svm_model.fit(X_train, y_train) y_score = svm_model.decision_function(X_test) # 获取单次运行的ROC数据 fpr, tpr, _ = roc_curve(y_test, y_score) # 将单次TPR插值到统一的FPR网格上 interp_tpr = np.interp(mean_fpr, fpr, tpr) # 强制设置FPR=0时TPR=0,确保曲线从原点出发 interp_tpr[0] = 0.0 tprs.append(interp_tpr) # 记录单次运行的AUC值 aucs.append(auc(fpr, tpr)) # 计算均值TPR和整体AUC mean_tpr = np.mean(tprs, axis=0) mean_tpr[-1] = 1.0 # 强制FPR=1时TPR=1,保证曲线终点正确 mean_auc = auc(mean_fpr, mean_tpr) std_tpr = np.std(tprs, axis=0) # 绘制均值ROC曲线 plt.figure(figsize=(8,6)) plt.plot(mean_fpr, mean_tpr, color='darkorange', lw=2, label=f'Mean ROC (AUC = {mean_auc:.2f})') # 绘制TPR的标准差置信区间 plt.fill_between(mean_fpr, mean_tpr - std_tpr, mean_tpr + std_tpr, color='orange', alpha=0.2) # 绘制对角线参考线 plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--') plt.xlim([0.0, 1.0]) plt.ylim([0.0, 1.05]) plt.xlabel('False Positive Rate') plt.ylabel('True Positive Rate') plt.title('Mean ROC Curve for Linear SVM (10 Runs)') plt.legend(loc="lower right") plt.show()
关键修复点
- 统一FPR网格:用
np.linspace(0,1,100)生成固定长度的FPR序列,避免每次运行的FPR点数不一致 - TPR插值:通过
np.interp将单次运行的TPR映射到统一FPR网格,保证所有TPR数组长度相同 - 强制原点/终点:手动设置
interp_tpr[0] = 0.0和mean_tpr[-1] = 1.0,确保曲线严格经过(0,0)和(1,1)
内容的提问来源于stack exchange,提问作者Ed9012
相关产品推荐
相关产品推荐

