precision_recall_curve 返回 precision、recall、thresholds 三组等长数组,分别对应各阈值下的精确率、召回率及阈值;其中 precision 和 recall 长度比 y_score 多 1,因包含阈值为 -inf 的全正预测点。

直接用 precision_recall_curve + matplotlib.pyplot.plot 就能画,但必须注意:它不接受概率阈值以外的输入,且默认不处理多分类或样本不平衡场景下的插值问题。
为什么 precision_recall_curve 返回三组数组?
它输出 precision、recall、thresholds 三个等长数组,对应每个可能的分类阈值下的精确率和召回率。注意:precision 和 recall 长度比 y_score 多 1(因为包含阈值为 -inf 时的全正预测点)。
- 输入
y_true必须是二值标签(0/1),不能是类别名或 -1/+1 -
y_score应该是模型输出的正类概率(如clf.predict_proba(X)[:, 1])或决策函数值(如clf.decision_function(X)),不能直接传predict()结果 - 若用
RandomForestClassifier等没实现predict_proba的模型,需先确认是否启用了class_weight='balanced'或改用decision_function
如何避免 PR 曲线起点跳变或末端失真?
原始 precision_recall_curve 输出的点在低召回区常稀疏,尤其当正样本极少时,recall 值可能只集中在几个离散点上,导致曲线“断层”。解决方法是手动插值或使用 sklearn.metrics.average_precision_score 辅助校验。
- 用
np.linspace(0, 1, 100)对recall插值,再用scipy.interpolate.interp1d得到平滑precision - 更稳妥的做法是:先调用
precision_recall_curve,再用plt.step(recall[::-1], precision[::-1], where='post')—— 注意反转顺序并指定where='post',才能匹配标准 PR 曲线阶梯定义 - 别忽略
average_precision_score(y_true, y_score)返回的是曲线下面积(AUC-PR),它对正负样本比例敏感,比 ROC-AUC 更适合不平衡数据
多分类场景下怎么画单个类别的 PR 曲线?
Scikit-learn 不提供开箱即用的多分类 PR 曲线绘制函数,必须手动做 one-vs-rest(OvR)转换。
立即学习“Python免费学习笔记(深入)”;
- 对目标类别
i,构造二值标签:y_true_binary = (y_true == i).astype(int) - 提取该类得分:
y_score_i = y_score[:, i](前提是y_score来自predict_proba或已归一化决策值) - 调用
precision_recall_curve(y_true_binary, y_score_i)即可,但要注意:如果某类在验证集中无正样本,precision数组会出现nan,需提前过滤或用pos_label显式指定 - 多个类别曲线叠加时,建议用不同线型+图例,并标注各曲线对应的
average_precision_score
PR 曲线真正难的不是画出来,而是确保 y_score 的语义和排序性与业务目标一致——比如推荐系统里“点击”是正样本,但模型输出的 predict_proba 可能受曝光偏差影响,此时直接画 PR 曲线会掩盖真实排序能力问题。


















