ROC-AUC-解释-评估分类模型的入门指南
ROC AUC 解释:评估分类模型的入门指南
原文:
towardsdatascience.com/roc-auc-explained-a-beginners-guide-to-evaluating-classification-models/
我们使用各种指标如准确率、精确度等评估了分类模型。
现在,在二元分类模型中,我们还有另一种评估模型的方法,那就是ROC AUC。
在这篇博客中,我们将讨论为什么我们需要另一个指标以及何时应该使用它。
要详细了解 ROC AUC,我们将考虑IBM HR Analytics数据集。
在这个数据集中,我们拥有 1,470 名员工的信息,例如他们的年龄、职位、性别、月收入、工作满意度等。
总共有 34 个特征描述每个员工。
我们还有一个目标列,‘离职’,如果员工离职则标记为‘是’,如果员工留任则标记为‘否’。
让我们来看看目标列的类别分布。

图片由作者提供
从上面的类别分布中,我们可以观察到数据集是不平衡的。
现在,我们需要根据员工是否会留在公司来构建一个基于这些数据的模型进行分类。
由于这是一个二元分类(是/否)任务,让我们在这个数据上应用逻辑回归算法。
代码:
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import confusion_matrix, classification_report
# Load the dataset
df = pd.read_csv("C:/HR-Employee-Attrition.csv")
# Drop non-informative columns
df.drop(['EmployeeNumber', 'Over18', 'EmployeeCount', 'StandardHours'], axis=1, inplace=True)
# Encode the target column
df['Attrition'] = df['Attrition'].map({'Yes': 1, 'No': 0})
# One-hot encode categorical features
df = pd.get_dummies(df, drop_first=True)
# Split features and target
X = df.drop('Attrition', axis=1)
y = df['Attrition']
# Train-test split
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, stratify=y, random_state=42
)
# Feature scaling
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# Train logistic regression model
model = LogisticRegression(max_iter=1000)
model.fit(X_train_scaled, y_train)
# Predict on test data
y_pred = model.predict(X_test_scaled)
# Predict probabilities for the positive class
y_prob = model.predict_proba(X_test_scaled)[:, 1]
# Confusion matrix and classification report
conf_matrix = confusion_matrix(y_test, y_pred)
report = classification_report(y_test, y_pred)
# Display results
print("Confusion Matrix:\n", conf_matrix)
print("\nClassification Report:\n", report)
混淆矩阵和分类报告

图片由作者提供
从上面的分类报告中,我们观察到准确率是 86%。然而,对于‘1’(离职 = 是,意味着员工离职)的召回率是 0.34,这表明模型仅正确识别了 34%离职的员工。
对于‘0’(离职 = 否,意味着员工留任)的召回率是 0.96,这表明模型正确识别了 96%留任的员工。
这种情况是由于数据集不平衡造成的。在这里,准确率可能会误导。
这是否意味着我们需要更改我们的算法?不。
我们需要改变评估模型的方式,对于不平衡数据集,评估分类模型的最佳方式是ROC AUC。
现在我们知道,还有另一种评估分类模型的方法,即 ROC AUC。但在探索 ROC AUC 之前,让我们先明确到目前为止发生了什么。
我们在 IBM HR 数据集上应用了逻辑回归,模型为每个员工提供了一个概率分数,表示他们离职的可能性有多大。

图片由作者提供
当我们生成混淆矩阵和分类报告时,它们基于一个阈值,默认值为 0.5。
如果预测概率大于 0.5,则认为员工已经离职;如果概率小于 0.5,则认为员工留任。
从这里,我们得到了 86%的准确率,但召回率仅为 34%。我们观察到准确率具有误导性,因此我们决定使用 ROC AUC 来评估模型。
ROC AUC
首先,我们将讨论接收者操作特征(ROC)曲线。
我们通过绘制真正率与假正率来获得 ROC 曲线。
我们已经知道分类报告是基于单个阈值的,但 ROC 曲线是通过计算所有可能阈值下的真正率(TPR)和假正率(FPR)然后绘制它们来生成的。
让我们取一个样本数据集,看看我们如何从中生成 ROC 曲线。

图片由作者提供
现在,对于上述数据,我们将在可能的阈值下计算 TPR 和 FPR,然后绘制它们。
可能的阈值是什么?
要生成 ROC 曲线,我们不需要在 0 到 1 之间的每个值上计算 TPR 和 FPR。
相反,我们使用数据集中的预测概率以及最大预测概率之上的一个值(因此所有预测都是负的,曲线从(0,0)开始)和最小预测概率之下的一个值作为阈值(因此所有预测都是正的,曲线在(1,1)结束)。
为什么不是 0 到 1 之间的每一个数作为阈值?
考虑我们的样本数据。我们有一个预测概率为 0.6592,我们将使用该值作为阈值来计算 TPR 和 FPR。
现在,在 0.6592 和 0.8718 之间,TPR 和 FPR 保持不变,只有当阈值超过预测概率时它们才会改变。
正因如此,我们使用唯一的预测概率作为阈值来生成 ROC 曲线。
现在,基于我们的样本数据,让我们生成 ROC 曲线并看看我们能观察到什么。
要生成 ROC 曲线,我们需要计算 TPR 和 FPR。
[
\text{真正率 (TPR)} = \frac{\text{真正性 (TP)}}{\text{真正性 (TP)} + \text{假阴性 (FN)}}
]
真正率(TPR)也称为召回率。
[
\text{假正率 (FPR)} = \frac{\text{假阳性 (FP)}}{\text{假阳性 (FP)} + \text{真阴性 (TN)}}
]
我们将要使用此样本数据计算 TPR 和 FPR 的阈值是{1, 0.9799, 0.9709, 0.8737, 0.8718, 0.6592, 0.6337, 0}。
让我们计算每个阈值下的 TPR 和 FPR。
[
\begin{aligned}
\mathbf{在阈值 0.9799 时:} & \[4pt]
\mathrm{True\ Positives\ (TP)} &= 1,\quad \mathrm{False\ Negatives\ (FN)} = 2,\
\mathrm{False\ Positives\ (FP)} &= 0,\quad \mathrm{True\ Negatives\ (TN)} = 3\[6pt]
\mathrm{TPR} &= \frac{\mathrm{TP}}{\mathrm{TP}+\mathrm{FN}} = \frac{1}{1+2} = \frac{1}{3} \approx 0.33\[6pt]
\mathrm{FPR} &= \frac{\mathrm{FP}}{\mathrm{FP}+\mathrm{TN}} = \frac{0}{0+3} = 0\[6pt]
\Rightarrow (\mathrm{FPR},,\mathrm{TPR}) &= (0,,0.33)
\end{aligned}
]
这样,我们在每个阈值下计算 TPR 和 FPR。

图片由作者提供
现在,让我们绘制 TPR 与 FPR 的关系图以获得 ROC 曲线。

图片由作者提供
这就是 ROC 曲线是如何生成的。由于我们只考虑了 6 个点的样本,因此很难清楚地观察和解释曲线。这里的主要目标是理解 ROC 曲线是如何生成的。
现在我们需要解释 ROC 曲线,为此我们将使用 Python 在我们的数据集上生成 ROC 曲线。
代码:
# Compute ROC curve and AUC
fpr, tpr, thresholds = roc_curve(y_test, y_prob)
roc_auc = auc(fpr, tpr)
# Print AUC
print(f"AUC: {roc_auc:.2f}")
# Plot ROC curve
plt.figure(figsize=(6,6))
plt.plot(fpr, tpr, label=f"ROC curve (AUC = {roc_auc:.2f})", linewidth=2)
plt.plot([0,1], [0,1], 'k--', label="Random guess (AUC = 0.5)")
plt.xlim([0,1])
plt.ylim([0,1.05])
plt.xlabel("False Positive Rate (FPR)")
plt.ylabel("True Positive Rate (TPR)")
plt.title("ROC Curve - Logistic Regression (HR Dataset)")
plt.legend(loc="lower right")
plt.grid(True)
plt.show()
图表:

图片由作者提供
让我们看看我们可以从 ROC 曲线中解读什么,不考虑 AUC,因为我们稍后会讨论 AUC。
在上述图中,y 轴代表真正率,即模型正确识别的实际正例数量,x 轴代表假正率,即模型产生的假正例数量。
在 ROC 曲线上,我们通过改变阈值来观察模型的行为。我们希望真正率尽可能高,同时保持假正率低,这意味着曲线应该向左上角上升。
如果曲线接近或沿着对角线,则模型实际上是在随机猜测,其性能不令人满意。
如果曲线位于对角线以下,则模型的性能非常差。
这样,我们可以了解模型在不同阈值下的性能。
现在,让我们讨论曲线下面积(AUC)。
我们已经看到,对于我们的数据,AUC 是0.81。

图片由作者提供
AUC 为 0.81 意味着如果你随机选择一个离职员工和一个留下来的员工,模型将给离职员工分配更高概率的概率为 81%。
现在,让我们使用样本数据集来了解 AUC 是如何计算的。
现在,我们再次回到我们使用样本数据生成的 ROC 曲线。

图片由作者提供
上图中的阴影区域表示 AUC。
现在让我们继续计算 AUC。
从点(0.00,0.33)到(0.33,0.33),曲线下方的面积由橙色矩形表示。
从点(0.33,0.33)到(0.67,0.33),曲线下方的面积由绿色矩形表示。
从点(0.67,0.33)到(1.00,0.33),曲线下方的面积由红色矩形表示。
现在要找到 AUC,我们需要计算矩形的面积并将它们相加。
$$
\text{橙色矩形: } l \times b = 0.33 \times 0.33 = 0.11
$$
$$
\text{绿色矩形: } l \times b = 0.34 \times 0.33 = 0.11
$$
$$
\text{红色矩形: } l \times b = 0.33 \times 0.33 = 0.11
$$
$$
\text{总 AUC} = 0.11 + 0.11 + 0.11 = 0.33
$$
这样我们计算 AUC。
在上述示例中,我们还可以找到不需要将其划分为逐点段来找到的区域,但在现实世界中我们看不到这样的 ROC 曲线。
现在,让我们考虑一个类似于现实世界案例的 ROC 曲线,并计算 AUC。

图像由作者提供
现在,让我们找到这个 ROC 曲线的 AUC。
这里我们有三个段。其中两个是梯形,另一个看起来像三角形。然而,我们不需要为每个形状使用单独的公式,因为矩形和三角形很少形成。
我们只使用梯形面积公式。
$$
\text{面积} = \tfrac{1}{2} \times (y_1 + y_2) \times (x_2 – x_1)
$$
现在,使用这个公式,让我们找到 AUC。
$$
\text{段 1: } (0.0,0.0) ;\rightarrow; (0.2,0.4) \
\text{面积} = \tfrac{1}{2} \times (0.0 + 0.4) \times (0.2 – 0.0) = 0.04
$$
这里,梯形公式自动简化为三角形面积的公式。
$$
\text{段 2: } (0.2,0.4) ;\rightarrow; (0.6,0.8) \
\text{面积} = \tfrac{1}{2} \times (0.4 + 0.8) \times (0.6 – 0.2) = 0.24
$$
$$
\text{段 3: } (0.6,0.8) ;\rightarrow; (1.0,1.0) \
\text{面积} = \tfrac{1}{2} \times (0.8 + 1.0) \times (1.0 – 0.6) = 0.36
$$
$$
\text{总 AUC} = 0.04 + 0.24 + 0.36 = 0.64
$$
这就是 AUC 是如何计算的。我们现在理解了我们如何得到 HR 数据集的 AUC 为 0.81。
但还有第二种计算 AUC 的方法。
再次,我们回到我们的样本数据集。

图像由作者提供
正例(1):[0.9799, 0.6592, 0.6337]
负例(0):[0.9709, 0.8737, 0.8718]
这里我们总共有 9 个正负对。
现在我们将每个正例与每个负例进行比较,以查看正例是否被排名更高。
$$
0.9799 😭\text{正}) > 0.9709 😭\text{负}) ;;;\Rightarrow;; \text{正被排名更高}
$$
$$
0.9799 😭\text{正}) > 0.8737 😭\text{负}) ;;;\Rightarrow;; \text{正被排名更高}
$$
$$
0.9799 😭\text{正}) > 0.8718 😭\text{负}) ;;;\Rightarrow;; \text{正被排名更高}
$$
$$
0.6592 😭\text{正类}) < 0.9709 😭\text{负类}) ;;;\Rightarrow;; \text{正类排名较低} $$ $$ 0.6592 😭\text{正类}) < 0.8737 😭\text{负类}) ;;;\Rightarrow;; \text{正类排名较低} $$ $$ 0.6592 😭\text{正类}) < 0.8718 😭\text{负类}) ;;;\Rightarrow;; \text{正类排名较低} $$ $$ 0.6337 😭\text{正类}) < 0.9709 😭\text{负类}) ;;;\Rightarrow;; \text{正类排名较低} $$ $$ 0.6337 😭\text{正类}) < 0.8737 😭\text{负类}) ;;;\Rightarrow;; \text{正类排名较低} $$ $$ 0.6337 😭\text{正类}) < 0.8718 😭\text{负类}) ;;;\Rightarrow;; \text{正类排名较低} $$ $$ \text{正确排名的配对数} = 3, \quad \text{总配对数} = 9, \quad \text{AUC} = \tfrac{3}{9} = 0.33 $$
这被称为AUC 排名方法。
我们使用两种方法对样本数据获得了相同的 0.33 值。
我们可以理解这一点
$$
\text{AUC} = \frac{\text{正确排名的配对数}}{\text{总配对数}}
$$
我们可以将 AUC 解释为随机选择的一个正类比随机选择的一个负类排名更高的概率。
既然我们已经了解了如何生成 ROC 曲线和计算 AUC,让我们讨论 ROC-AUC 的重要性。
当我们发现准确率具有误导性时,我们使用了 ROC-AUC。但除了 ROC-AUC,我们可能会问:为什么不在所有阈值值上运行循环,计算准确率和其他指标,然后选择最佳阈值?
是的,这是可能的。然而,当我们比较两个模型时,我们不能仅基于它们的最佳阈值进行比较,因为不同的模型可能有不同的最佳阈值。
ROC-AUC 给我们一个单一的数字来总结模型的表现,并允许跨不同模型进行比较。
另一点是,最佳阈值取决于我们选择的指标。
“最佳”阈值取决于我们是否优化准确率、精确率、召回率或 F1 分数。ROC-AUC 是阈值无关的,使其成为模型质量的更一般性度量。
最后,ROC-AUC 捕捉了模型的排名能力,这使得它在处理不平衡数据集时特别有用。
数据集
本文使用的 IBM HR Analytics 员工流失数据集 来自 Kaggle,该数据集在 CC0 (公共领域) 许可下,这使得它在分析和发表中安全使用。
我希望你觉得这篇文章有帮助。
如果你还没有阅读我最近关于机器学习和金融背景下 Gini 系数 的博客,你可以在这里查看。
如果你想阅读更多我的作品,你还可以在 Medium 和 LinkedIn 上找到。
感谢阅读!

浙公网安备 33010602011771号