机器学习 - AUC - ROC 曲线

AUC - ROC 曲线

在分类中,有许多不同的评估指标。最受欢迎的是准确率 (accuracy),它衡量模型正确的频率。这是一个很好的指标,因为它易于理解,并且通常希望获得最多的正确猜测。但在某些情况下,您可能会考虑使用另一个评估指标。

另一个常见的指标是 AUC,即接收者操作特征(ROC)曲线下的面积。ROC 曲线绘制了不同分类阈值下的真正例(TP)率和假正例(FP)率。阈值是二元分类中区分两个类别的不同概率截断值。它使用概率来告诉我们模型区分类别的能力。

假设我们有一个不平衡的数据集,其中大部分数据都是一个值。我们可以通过预测多数类来获得模型的高准确率。

实例

import numpy as np
from sklearn.metrics import accuracy_score, confusion_matrix, roc_auc_score, roc_curve

n = 10000
ratio = .95
n_0 = int((1-ratio) * n)
n_1 = int(ratio * n)

y = np.array([0] * n_0 + [1] * n_1)
# 以下是从一个假设的模型中获得的概率,该模型总是预测多数类
# 预测类别 1 的概率为 100%
y_proba = np.array([1]*n)
y_pred = y_proba > .5

print(f'准确率:{accuracy_score(y, y_pred)}')
cf_mat = confusion_matrix(y, y_pred)
print('混淆矩阵')
print(cf_mat)
print(f'类别 0 的准确率:{cf_mat[0][0]/n_0}')
print(f'类别 1 的准确率:{cf_mat[1][1]/n_1}')

亲自试一试

尽管我们获得了非常高的准确率,但模型没有提供有关数据的任何信息,因此它没有用。我们 100% 准确地预测了类别1,而 0% 准确地预测了类别 0。以准确率为代价,拥有一个能够在一定程度上区分两个类别的模型可能更好。

实例

# 以下是从一个不总是预测众数的假设模型中获得的概率
y_proba_2 = np.array(
    np.random.uniform(0, .7, n_0).tolist() +
    np.random.uniform(.3, 1, n_1).tolist()
)
y_pred_2 = y_proba_2 > .5

print(f'准确率:{accuracy_score(y, y_pred_2)}')
cf_mat = confusion_matrix(y, y_pred_2)
print('混淆矩阵')
print(cf_mat)
print(f'类别 0 的准确率:{cf_mat[0][0]/n_0}')
print(f'类别 1 的准确率:{cf_mat[1][1]/n_1}')

亲自试一试

对于第二组预测,我们的准确率没有第一组高,但每个类别的准确率更加平衡。使用准确率作为评估指标,我们会将第一个模型评为比第二个模型更高,尽管它没有告诉我们任何关于数据的信息。

在这种情况下,使用另一个评估指标,如 AUC,会更好。

import matplotlib.pyplot as plt

def plot_roc_curve(true_y, y_prob):
    """
    基于概率绘制 ROC 曲线
    """

    fpr, tpr, thresholds = roc_curve(true_y, y_prob)
    plt.plot(fpr, tpr)
    plt.xlabel('假正例率')
    plt.ylabel('真正例率')

实例

模型 1:

plot_roc_curve(y, y_proba)
print(f'model 1 AUC score: {roc_auc_score(y, y_proba)}')

亲自试一试

结果:

model 1 AUC score: 0.5

实例

模型 2:

plot_roc_curve(y, y_proba_2)
print(f'模型 2 AUC 得分:{roc_auc_score(y, y_proba_2)}')

亲自试一试

结果:

模型 2 AUC 得分:0.8270551578947367

AUC 得分约为 .5 表示模型无法区分两个类别,曲线将类似于斜率为 1 的直线。AUC 得分接近 1 表示模型具有区分两个类别的能力,并且曲线将更接近图的左上角。

概率

由于 AUC 是一个利用类别预测概率的指标,因此即使两个模型的准确率相似,具有更高 AUC 得分的模型也会比具有较低得分的模型更可靠。这是因为 AUC 考虑了预测的概率。在预测未来数据时,具有更高 AUC 得分的模型更有可能提供更高的准确率。

在下面的数据中,我们有两组来自假设模型的概率。第一组在预测两个类别时的概率“信心”不足(概率接近 0.5)。第二组在预测两个类别时“信心”更足(概率接近 0 或 1 的极端值)。

实例

import numpy as np

n = 10000
y = np.array([0] * n + [1] * n)
#
y_prob_1 = np.array(
    np.random.uniform(.25, .5, n//2).tolist() +
    np.random.uniform(.3, .7, n).tolist() +
    np.random.uniform(.5, .75, n//2).tolist()
)
y_prob_2 = np.array(
    np.random.uniform(0, .4, n//2).tolist() +
    np.random.uniform(.3, .7, n).tolist() +
    np.random.uniform(.6, 1, n//2).tolist()
)

print(f'模型 1 的准确率:{accuracy_score(y, y_prob_1>.5)}')
print(f'模型 2 的准确率:{accuracy_score(y, y_prob_2>.5)}')

print(f'模型 1 的 AUC 得分:{roc_auc_score(y, y_prob_1)}')
print(f'模型 2 的 AUC 得分:{roc_auc_score(y, y_prob_2)}')

亲自试一试

实例

绘制模型 1 的图:

plot_roc_curve(y, y_prob_1)

亲自试一试

结果:

实例

绘制模型 2 的图:

fpr, tpr, thresholds = roc_curve(y, y_prob_2)
plt.plot(fpr, tpr)

亲自试一试

结果:

尽管两个模型的准确度相似,但 AUC 得分较高的模型将更可靠,因为它考虑了预测的概率。在预测未来数据时,它更有可能为您提供更高的准确性。