我使用 sklearn 计算roc_auc_score了一个包含 72 个实例的数据集。准确率为 97%(2 次错误分类),但 ROC AUC 得分为 1.0。这怎么可能?我认为即使是一次错误分类也应该将分数降至略低于 1.0。
# Python 3.6.4
# numpy==1.14.3
# scikit-learn==0.19.1
# scipy==1.1.0
from sklearn import metrics
import numpy as np
y_true = np.array([0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0])
y_prob = np.array([0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.1, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.7, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1, 0.1, 0.0, 0.0, 0.9, 0.0, 0.0, 0.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.1, 0.1, 0.0, 0.0, 0.7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.1, 0.0, 0.0, 0.1, 0.1, 0.0, 0.9, 0.0, 0.0, 0.4, 0.0, 0.0, 0.0])
# Show which actuals do not match their expected probabilities
for index, (actual, predicted_prob) in enumerate(zip(y_true, y_prob)):
if (actual == 1 and predicted_prob <= 0.5) or (actual == 0 and predicted_prob > 0.5):
print (f'Mismatch at index {index}. Actual={actual}, predicted_prob={predicted_prob}')
rocauc = metrics.roc_auc_score(y_true, y_prob)
print (f'ROCAUC: {rocauc}')
# Outputs:
# Mismatch at index 14. Actual=1.0, predicted_prob=0.5
# Mismatch at index 68. Actual=1.0, predicted_prob=0.4
# ROCAUC: 1.0
然后我调试了分数计算本身并查看了坐标 ROC 输出。
# In sklearn/metrics/ranking.py, line 271:
--> 271 fpr, tpr, tresholds = roc_curve(y_true, y_score,
272 sample_weight=sample_weight)
ipdb> fpr
array([0. , 0. , 0. , 0.18181818, 1. ])
ipdb> tpr
array([0.33333333, 0.66666667, 1. , 1. , 1. ])
ipdb> tresholds
array([0.9, 0.7, 0.4, 0.1, 0. ])
# coords = []
# for x, y in zip(fpr, tpr):
# coords.append((x, y))
ipdb> pp coords
[(0.0, 0.3333333333333333),
(0.0, 0.6666666666666666),
(0.0, 1.0),
(0.18181818181818182, 1.0),
(1.0, 1.0)]
所有这些坐标都在 x=0 或 y=1 上,这意味着 ROCAUC 显示为 1.0。我能想到的唯一合理的解释是,如果 alg 有更多的 fpr/tpr 点,它将显示一条非常紧的曲线,永远不会达到 x,y = (0, 1),并且 ROCAUC 将接近 1,但是不完全是 1. 这是一个合理的解释还是我错过了什么?