Roc_auc_score()和 auc()的结果不同

在 scikit-learn 中,我很难理解 roc_auc_score()auc()之间的区别(如果有的话)。

进出口试图预测一个二进制输出与不平衡类(约1.5% 的 Y = 1)。

分类器

model_logit = LogisticRegression(class_weight='auto')
model_logit.fit(X_train_ridge, Y_train)

洛克曲线

false_positive_rate, true_positive_rate, thresholds = roc_curve(Y_test, clf.predict_proba(xtest)[:,1])

AUC 的

auc(false_positive_rate, true_positive_rate)
Out[490]: 0.82338034042531527

还有

roc_auc_score(Y_test, clf.predict(xtest))
Out[493]: 0.75944737191205602

有人能解释一下这种区别吗?我以为两者都只是在计算 ROC 曲线下的面积。可能是因为不平衡的数据集,但我不能找出为什么。

谢谢!

80434 次浏览

AUC并不总是 ROC曲线的 曲线下面积。曲线下面积是 一些曲线下的一个(抽象的)面积,所以它比 AUROC更像 将军。对于不平衡类,最好找到精度-召回曲线的 AUC。

请参阅 sklearn source for roc_auc_score:

def roc_auc_score(y_true, y_score, average="macro", sample_weight=None):
# <...> docstring <...>
def _binary_roc_auc_score(y_true, y_score, sample_weight=None):
# <...> bla-bla <...>
    

fpr, tpr, tresholds = roc_curve(y_true, y_score,
sample_weight=sample_weight)
return auc(fpr, tpr, reorder=True)
    

return _average_binary_score(
_binary_roc_auc_score, y_true, y_score, average,
sample_weight=sample_weight)

正如您所看到的,它首先得到一个 roc 曲线,然后调用 auc()来获得面积。

我猜你的问题是 predict_proba()呼叫。对于一个正常的 predict()输出总是相同的:

import numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_curve, auc, roc_auc_score


est = LogisticRegression(class_weight='auto')
X = np.random.rand(10, 2)
y = np.random.randint(2, size=10)
est.fit(X, y)


false_positive_rate, true_positive_rate, thresholds = roc_curve(y, est.predict(X))
print auc(false_positive_rate, true_positive_rate)
# 0.857142857143
print roc_auc_score(y, est.predict(X))
# 0.857142857143

如果为此更改上面的代码,有时会得到不同的输出:

false_positive_rate, true_positive_rate, thresholds = roc_curve(y, est.predict_proba(X)[:,1])
# may differ
print auc(false_positive_rate, true_positive_rate)
print roc_auc_score(y, est.predict(X))

predict只返回一个类或另一个类。然后用分类器上的 predict结果计算一个 ROC,它只有三个阈值(试用所有一个类,其他类都不重要,以及在两者之间)。ROC 曲线如下:

      ..............................
|
|
|
......|
|
|
|
|
|
|
|
|
|
|
|

同时,predict_proba()返回一个完整的概率范围,因此现在您可以在数据上设置三个以上的阈值。

             .......................
|
|
|
...|
|
|
.....|
|
|
....|
.|
|
|
|
|

所以是不同的区域。

当您使用 y _ pred (类标签)时,您已经决定 当你使用 y _ prob (正类概率) 你对门槛持开放态度,ROC 曲线应该会有所帮助 你来决定门槛。

对于第一种情况,你使用的是概率:

y_probs = clf.predict_proba(xtest)[:,1]
fp_rate, tp_rate, thresholds = roc_curve(y_true, y_probs)
auc(fp_rate, tp_rate)

当你这样做的时候,你是在考虑 AUC 的“之前”采取 关于你将要使用的阈值的决定。

在第二种情况下,您使用的是预测(而不是概率) , 在这种情况下,使用“预测”,而不是“预测 _ 探测器”为双方和你 应该得到同样的结果。

y_pred = clf.predict(xtest)
fp_rate, tp_rate, thresholds = roc_curve(y_true, y_pred)
print auc(fp_rate, tp_rate)
# 0.857142857143


print roc_auc_score(y, y_pred)
# 0.857142857143