You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

手动计算TPR/FPR与scikit-learn ROC曲线输出结果不一致问题

问题原因与修正方案

这是代码编写错误+对scikit-learn接口默认逻辑理解偏差共同导致的,不属于函数设计的预期差异。

错误1:混淆矩阵的四类样本取值完全颠倒

scikit-learn的confusion_matrix输出矩阵遵循「行对应真实标签、列对应预测标签、标签按升序排列」的规则,布尔类型的升序为False < True,因此矩阵索引和样本类别的对应关系为:

  • cm[0,0]:真实为False、预测为False → 真负例(TN)
  • cm[0,1]:真实为False、预测为True → 假正例(FP)
  • cm[1,0]:真实为True、预测为False → 假负例(FN)
  • cm[1,1]:真实为True、预测为True → 真正例(TP)

你原有代码把四个类别的定义完全写反,计算出的实际是负类的分类指标,因此数值和正类指标刚好呈「和为1」的互补关系:你算出的0.3611 = 1 - 0.6389,0.4567 = 1 - 0.5433,和roc_curve返回的中间值刚好互补。

错误2:对roc_curve的阈值逻辑理解不到位

你传入的是布尔类型的预测数组,roc_curve默认将排序靠后的大值标签(即布尔值True)作为正类,返回的阈值数组[2, 1, 0]是为了覆盖ROC曲线的三个关键节点:

  • 阈值为2:所有样本预测值都小于2,全部判定为负类,对应FPR=0、TPR=0,是ROC曲线的左下角起点
  • 阈值为1:判定规则为预测值≥1则判为正类,布尔值True等价于数值1、False等价于0,此时的判定逻辑就是直接使用你传入的离散预测结果,对应的FPR、TPR就是该分类规则下的真实指标
  • 阈值为0:所有样本预测值都≥0,全部判定为正类,对应FPR=1、TPR=1,是ROC曲线的右上角终点

修正方案

把混淆矩阵的四类样本取值按正确对应关系调整即可,修正后的代码如下:

from sklearn.metrics import confusion_matrix, roc_curve
cm = confusion_matrix(self.real_values_discrete, self.predictions_discrete)
_tn = cm[0, 0]
_fp = cm[0, 1]
_fn = cm[1, 0]
_tp = cm[1, 1]
_tpr = _tp / (_tp + _fn)
_fpr = _fp / (_fp + _tn)
print(_fpr, _tpr)
# 输出结果和roc_curve返回的中间值完全一致:0.6388888888888888 0.5433070866141733

如果你的业务场景中需要将False作为正类,只需要在调用roc_curve和confusion_matrix时显式传入参数pos_label=False,两个接口的计算结果就会和你最初手动计算的数值对齐。

内容的提问来源于stack exchange,提问作者teriyaki.sub47

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 06:03:13