不使用scikit-learn如何基于TP/FP/FN数据绘制ROC-AUC曲线
实现步骤
首先需要明确:ROC曲线的横轴为假阳性率(FPR),纵轴为真阳性率(TPR=Recall),绘制逻辑是先将所有检测结果按置信度从高到低排序,逐点累加得到不同阈值下的累计TP、FP、FN,再计算对应FPR、TPR,最后用梯形法计算AUC。你提供的7组(TP,FP,FN)如果是不同阈值下的全局统计值,可直接按以下步骤实现:
1. 完整代码实现
import matplotlib.pyplot as plt # 你的原始数据 data = [(12, 0, 0), (5, 2, 2), (10, 0, 1), (7, 1, 1), (13, 0, 0), (7, 2, 2), (11, 0, 2)] def calculate_recall_precision(data): precisions_bundle = [] recalls_bundle = [] for tp, fp, fn in data: precision = tp / (tp + fp) if (tp + fp) != 0 else 0 recall = tp / (tp + fn) if (tp + fn) != 0 else 0 precisions_bundle.append(precision) recalls_bundle.append(recall) return (precisions_bundle, recalls_bundle) # 额外实现FPR计算、AUC计算、ROC绘制函数 def calculate_fpr(data, total_neg_samples): fpr_bundle = [] for tp, fp, fn in data: fpr = fp / total_neg_samples if total_neg_samples !=0 else 0 fpr_bundle.append(fpr) return fpr_bundle def calculate_auc(fpr_list, tpr_list): # 先按FPR从小到大排序 sorted_pairs = sorted(zip(fpr_list, tpr_list), key=lambda x: x[0]) sorted_fpr = [p[0] for p in sorted_pairs] sorted_tpr = [p[1] for p in sorted_pairs] # 补全(0,0)和(1,1)端点避免计算误差 if sorted_fpr[0] != 0: sorted_fpr.insert(0, 0) sorted_tpr.insert(0, 0) if sorted_fpr[-1] != 1: sorted_fpr.append(1) sorted_tpr.append(sorted_tpr[-1]) # 梯形法积分计算AUC auc = 0.0 for i in range(1, len(sorted_fpr)): width = sorted_fpr[i] - sorted_fpr[i-1] height = (sorted_tpr[i] + sorted_tpr[i-1]) / 2 auc += width * height return auc, sorted_fpr, sorted_tpr def plot_roc(fpr, tpr, auc_score): plt.figure(figsize=(8,6)) plt.plot(fpr, tpr, color='darkorange', lw=2, label=f'ROC curve (AUC = {auc_score:.3f})') 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 (FPR)') plt.ylabel('True Positive Rate (TPR/Recall)') plt.title('Receiver Operating Characteristic') plt.legend(loc="lower right") plt.show() # 调用示例 if __name__ == "__main__": # 注意:total_neg_samples为你的数据集中总负样本(背景)数量,需要你根据实际数据集替换 total_neg_samples = 100 # 示例值,替换为你的真实值 precisions, tpr_list = calculate_recall_precision(data) fpr_list = calculate_fpr(data, total_neg_samples) auc_score, sorted_fpr, sorted_tpr = calculate_auc(fpr_list, tpr_list) print(f"AUC值为:{auc_score:.3f}") plot_roc(sorted_fpr, sorted_tpr, auc_score)
2. 注意事项
- 如果你的7组(TP,FP,FN)是单张图像独立统计的结果,需要先把所有图像的检测框按置信度从高到低排序,逐一遍历每个检测框,累加全局的TP、FP数量,再结合总正样本数计算每个阈值点的TPR和FPR,再进行后续计算。
- 代码中的
total_neg_samples需要替换为你数据集的总背景负样本数量,若你不需要严格的FPR数值,也可以将横轴替换为查准率绘制PR曲线,PR曲线更适合目标检测任务的效果评估。
内容的提问来源于stack exchange,提问作者RZAMarefat
相关产品推荐
相关产品推荐

