roc_auc_score() 和 auc() 的不同结果
Different result with roc_auc_score() and auc()
我无法理解 scikit-learn 中 roc_auc_score()
和 auc()
之间的区别(如果有的话)。
我想预测不平衡 类 的二进制输出(Y=1 时约为 1.5%)。
分类器
model_logit = LogisticRegression(class_weight='auto')
model_logit.fit(X_train_ridge, Y_train)
Roc 曲线
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 曲线下的面积。可能是因为数据集不平衡,但我不知道为什么。
谢谢!
AUC 并不总是 ROC 曲线下的面积。 Area Under the Curve 是 some 曲线下的一个(抽象的)区域,所以它是一个比 AUROC 更笼统的东西。在不平衡的情况下 类,找到精确召回曲线的 AUC 可能更好。
请参阅 roc_auc_score
的 sklearn 源代码:
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
returns 只有一个 class 或另一个。然后你用classifier上predict
的结果计算一个ROC,只有三个阈值(试验所有一个class,所有其他class,并且在之间)。您的 ROC 曲线如下所示:
..............................
|
|
|
......|
|
|
|
|
|
|
|
|
|
|
|
同时,predict_proba()
returns 整个概率范围,因此现在您可以在数据上设置三个以上的阈值。
.......................
|
|
|
...|
|
|
.....|
|
|
....|
.|
|
|
|
|
因此区域不同。
当您使用 y_pred(class 标签)时,您已经决定
门槛。当你使用 y_prob (正 class 概率)
您对阈值持开放态度,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 'before'
决定您将使用的阈值。
在第二种情况下,您使用的是预测(而不是概率),
在这种情况下,对您和您都使用 'predict' 而不是 'predict_proba'
应该得到相同的结果。
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
我无法理解 scikit-learn 中 roc_auc_score()
和 auc()
之间的区别(如果有的话)。
我想预测不平衡 类 的二进制输出(Y=1 时约为 1.5%)。
分类器
model_logit = LogisticRegression(class_weight='auto')
model_logit.fit(X_train_ridge, Y_train)
Roc 曲线
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 曲线下的面积。可能是因为数据集不平衡,但我不知道为什么。
谢谢!
AUC 并不总是 ROC 曲线下的面积。 Area Under the Curve 是 some 曲线下的一个(抽象的)区域,所以它是一个比 AUROC 更笼统的东西。在不平衡的情况下 类,找到精确召回曲线的 AUC 可能更好。
请参阅 roc_auc_score
的 sklearn 源代码:
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
returns 只有一个 class 或另一个。然后你用classifier上predict
的结果计算一个ROC,只有三个阈值(试验所有一个class,所有其他class,并且在之间)。您的 ROC 曲线如下所示:
..............................
|
|
|
......|
|
|
|
|
|
|
|
|
|
|
|
同时,predict_proba()
returns 整个概率范围,因此现在您可以在数据上设置三个以上的阈值。
.......................
|
|
|
...|
|
|
.....|
|
|
....|
.|
|
|
|
|
因此区域不同。
当您使用 y_pred(class 标签)时,您已经决定 门槛。当你使用 y_prob (正 class 概率) 您对阈值持开放态度,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 'before' 决定您将使用的阈值。
在第二种情况下,您使用的是预测(而不是概率), 在这种情况下,对您和您都使用 'predict' 而不是 'predict_proba' 应该得到相同的结果。
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