ROC曲线通过roc_curve函数输入真实标签和预测概率,输出FPR、TPR及阈值,再用auc计算面积;需确保y_score为正类概率,不可用硬分类结果。

ROC曲线怎么画?关键在roc_curve和auc
ROC曲线本质是调节分类阈值,观察真正率(TPR)和假正率(FPR)的变化轨迹。Python里最直接的方式是用sklearn.metrics.roc_curve拿到各阈值下的点,再用sklearn.metrics.auc算AUC值。
注意:输入必须是模型输出的**预测概率**(如clf.predict_proba(X)[:, 1]),不是硬分类标签。传入y_true和y_score后,函数返回三个数组:fpr、tpr、thresholds。
常见错误:把clf.predict(X)的结果当y_score传进去——这会导致只有两个点(阈值0和1),画不出曲线。
- 二分类场景下,
y_score应为正类概率,不能是logit或决策函数原始分(除非你明确做了sigmoid映射) - 多分类需先转为one-vs-rest形式,对每个类单独调用
roc_curve - 若模型不支持概率输出(如SVM默认无
predict_proba),得用CalibratedClassifierCV先校准
PR曲线为什么比ROC更关注小样本/不平衡数据?
PR曲线横轴是查准率(Precision),纵轴是查全率(Recall),它不依赖负样本数量。当负样本远多于正样本时(比如欺诈检测中99.9%是正常交易),ROC会因大量易判负样本而显得“过于乐观”,而PR曲线能更敏感地暴露模型在正样本上的缺陷。
立即学习“Python免费学习笔记(深入)”;
画法类似,但用的是precision_recall_curve和average_precision_score。注意它的AUC叫AP(Average Precision),不是简单用auc(precision, recall)——因为PR曲线不是单调的,average_precision_score内部做了插值处理。
- 传入参数和ROC一致:
y_true和y_score - 返回
precision、recall、thresholds,但precision数组末尾会补1.0(对应recall=0时的边界情况) - 如果正样本极少(比如
y_true.sum() == 0),precision_recall_curve会报ValueError,需提前检查
用plot_roc_curve和plot_precision_recall_curve快速可视化
sklearn 0.22+ 提供了封装好的绘图函数,底层仍调用前述指标计算逻辑,但省去了手动plt.plot步骤,适合快速诊断。
它们接受已拟合的分类器和测试集,自动调用predict_proba或decision_function(根据模型能力选择)。但要注意:这些函数只支持单个分类器,不能直接对比多个模型。
- 若模型没有
predict_proba但有decision_function(如LinearSVC),函数会自动 fallback 使用后者 - 多分类时,这两个函数默认只画“one-vs-rest”中第一个类的曲线,想看全部得循环调用
- 返回的对象含
roc_auc或average_precision属性,可直接取值,不用再单独调用auc或average_precision_score
评估时容易忽略的细节:阈值对齐与置信度校准
ROC和PR都依赖模型输出的概率可信度。如果模型输出的分数不能反映真实概率(比如predict_proba结果集中在0.4~0.6之间),那么曲线形状和AUC值都会失真——高AUC可能只是“排序能力强”,不代表实际部署时阈值好调。
这时候需要做概率校准:CalibratedClassifierCV(带cv='prefit'可复用训练好的模型)、或用sklearn.calibration.calibration_curve画可靠性图验证。
- 未校准的树模型(如RandomForest)常出现概率偏移,直接画ROC可能高估性能
- 交叉验证时,务必在每折内独立校准,不能先校准再交叉验证,否则造成数据泄露
- 同一组
y_score同时画ROC和PR是可以的,但二者AUC不可直接比较大小——量纲不同,目标也不同


















