关于sklearn中roc_curve()返回fpr与thresholds维度不一致及precision_recall_curve()维度差1的技术问询
关于sklearn中roc_curve和precision_recall_curve维度差异的解答
先直接拆解你的两个疑问,都是这些指标计算函数的内部逻辑导致的,我来逐一说明:
一、roc_curve中fpr与thresholds维度不一致的原因
你看到的fpr.shape和thresholds.shape不匹配,核心原因是sklearn的roc_curve默认会自动去除重复的(fpr, tpr)点,只保留能让ROC曲线产生变化的关键阈值结果。
具体逻辑:
thresholds返回的是所有去重后的预测分数值(按降序排列),也就是所有可能用来划分正负类的候选阈值。- 但当多个不同阈值计算出的fpr和tpr完全相同时,这些点在ROC曲线上是重合的,不会改变曲线形状,所以sklearn会自动合并这些重复点,只保留一组(fpr, tpr)。这就导致最终
fpr和tpr的长度远小于thresholds的长度。
如果想让三者维度完全一致,调用roc_curve时可以关闭自动去重逻辑:
from sklearn.metrics import roc_curve fpr,tpr,thresholds = roc_curve(y_train_5,y_scores, drop_intermediate=False) # 此时fpr.shape会和thresholds.shape保持一致
二、precision_recall_curve中precisions比thresholds多一个维度的原因
这个差异是函数的计算规则决定的,本质是多了一个极端阈值场景的结果:
当阈值设置为比所有预测分数都大时,没有任何样本会被分类为正类。此时:
- recall(召回率)为0(没有识别出任何正样本)
- precision(精确率)在sklearn中被定义为1(因为精确率公式是TP/(TP+FP),此时TP和FP均为0,分母为0,sklearn做了特殊处理)
precision_recall_curve会把这个极端场景的precision值添加到precisions数组的末尾,而thresholds只包含实际存在的预测分数(去重后的),所以precisions的长度会比thresholds多1。
举个简单例子:如果你的预测分数只有[0.3, 0.5, 0.7]三个值,那么thresholds就是这三个值,precisions会包含这三个阈值对应的precision,再加上阈值>0.7时的precision(即1),长度为4,比thresholds多1。
内容的提问来源于stack exchange,提问作者XXX
相关产品推荐
相关产品推荐

