趋近智
尽管准确度——正确预测与总预测的简单比率——提供了模型性能的基本衡量,但它通常无法全面反映情况,尤其是在分类任务中。仅依赖准确度可能会产生误导,特别是在处理不平衡数据集(其中一个类别的数量显著超过其他类别)或不同类型错误造成的代价显著不同时。为了更好地了解您的模型能力,您需要查看源自混淆矩阵的更全面的评估指标。
混淆矩阵是一个表格,总结了分类算法的性能。它通过比较一组数据的实际类别标签与预测类别标签,将预测结果分为四类。对于二元分类问题(类别通常标记为正类和负类),该矩阵如下所示:
理解这四个组成部分是计算更多有用指标的关键。
from sklearn.metrics import confusion_matrix
import numpy as np
# 实际标签和预测标签示例
y_true = np.array([1, 0, 1, 1, 0, 0, 1, 0, 0, 1]) # 1:正类,0:负类
y_pred = np.array([1, 0, 0, 1, 0, 1, 1, 0, 0, 1]) # 模型的预测
# 计算混淆矩阵
cm = confusion_matrix(y_true, y_pred)
print("混淆矩阵:")
print(cm)
# 输出解释:
# [[真负例, 假正例],
# [假负例, 真正例]]
# [[4 1] <- 实际负类
# [1 4]] <- 实际正类
# ^ ^
# 预测负类 预测正类
在此示例中,我们得到: TN = 4 (正确预测为负类) FP = 1 (错误预测为正类) FN = 1 (错误预测为负类) TP = 4 (正确预测为正类)
精确率回答了这个问题:“在模型预测为正类的所有实例中,有多少是实际的正类?”它侧重于模型做出的正类预测的正确性。
当假正例的代价很高时,高精确率是需要的。例如:
from sklearn.metrics import precision_score
precision = precision_score(y_true, y_pred)
print(f"精确率: {precision:.4f}") # 输出: 精确率: 0.8000
在我们的示例中,。80% 被预测为正类的实例实际上是正类。
召回率回答了这个问题:“在所有实际正类实例中,模型正确识别了多少?”它衡量了模型找出数据集中所有相关案例的能力。
当假负例的代价很高时,高召回率很重要。漏掉一个正类实例是不好的。例如:
from sklearn.metrics import recall_score
recall = recall_score(y_true, y_pred)
print(f"召回率: {recall:.4f}") # 输出: 召回率: 0.8000
在我们的示例中,。模型正确识别了 80% 的实际正类实例。
通常,精确率和召回率之间存在反向关系。调整模型的分类阈值(实例被分类为正类时的概率值)通常会增加一个指标,同时减少另一个。非常高的阈值会导致高精确率但低召回率(只做出置信度高的预测),而低阈值会导致高召回率但低精确率(识别出更多正类,但假正例也会增加)。理解这种权衡对于根据特定目标调整模型非常重要。
F1分数提供了一个单一指标,平衡了精确率和召回率。它是两者的调和平均值,计算方式如下:
调和平均值对较低的值赋予更大的权重。因此,F1分数只有当精确率和召回率都高时才会高。当您需要在精确率和召回率之间取得平衡,或在处理不平衡类别时,它特别有用。
from sklearn.metrics import f1_score
f1 = f1_score(y_true, y_pred)
print(f"F1分数: {f1:.4f}") # 输出: F1分数: 0.8000
在我们的示例中,。
特异度衡量了被正确识别的实际负例的比例。它回答了这个问题:“在所有实际负例实例中,模型正确识别了多少?”
特异度本质上是负类的“召回率”。当正确识别负类是主要目标时,它很重要。它也直接相关于假正例率 (FPR),其中 。
# 特异度不直接在 sklearn.metrics 顶级函数中,但可以从混淆矩阵轻松得出
tn, fp, fn, tp = confusion_matrix(y_true, y_pred).ravel()
specificity = tn / (tn + fp)
print(f"特异度: {specificity:.4f}") # 输出: 特异度: 0.8000
在我们的示例中,。
接收者操作特征 (ROC) 曲线是一个有用的图形工具,用于评估二元分类器。它绘制了在不同分类阈值下的真阳性率(召回率)与假阳性率(FPR = 1 - 特异度)的关系。
ROC 曲线上的每个点代表特定决策阈值下的 TPR 和 FPR。一个表现不比随机猜测好的模型,其 ROC 曲线将接近对角线 (FPR = TPR)。一个好的分类器,其 ROC 曲线会趋向左上角,表明在低 FPR 下具有高 TPR。
曲线下面积 (AUC) 量化了分类器在所有可能阈值下的整体性能。AUC 值范围从 0 到 1:
AUC 之所以有用,因为它提供了单一数字的性能总结,独立于所选阈值。与准确度相比,它对类别不平衡不那么敏感。
from sklearn.metrics import roc_curve, auc, RocCurveDisplay
import matplotlib.pyplot as plt # 注意:绘图通常需要 matplotlib
# 假设您有正类的预测概率
# 为演示目的,我们创建一些虚拟概率
# 实际应用中,使用 model.predict_proba(X_test)[:, 1]
y_scores = np.array([0.9, 0.4, 0.3, 0.8, 0.2, 0.6, 0.7, 0.3, 0.1, 0.75])
fpr, tpr, thresholds = roc_curve(y_true, y_scores)
roc_auc = auc(fpr, tpr)
print(f"AUC: {roc_auc:.4f}") # 输出取决于 y_scores,例如:AUC: 0.8800
# 您可以使用 RocCurveDisplay 或手动绘制 fpr 与 tpr 的图
# Plotly 图表示例(需要安装 plotly)
import plotly.graph_objects as go
fig = go.Figure()
fig.add_trace(go.Scatter(x=fpr, y=tpr,
mode='lines',
name=f'ROC 曲线 (AUC = {roc_auc:.2f})',
line=dict(color='#1f77b4', width=2))) # 蓝色线条
fig.add_trace(go.Scatter(x=[0, 1], y=[0, 1],
mode='lines',
name='随机机会',
line=dict(color='#adb5bd', width=2, dash='dash'))) # 灰色虚线
fig.update_layout(
title='接收者操作特征 (ROC) 曲线',
xaxis_title='假正例率 (1 - 特异度)',
yaxis_title='真正例率 (召回率)',
xaxis=dict(range=[0.0, 1.0]),
yaxis=dict(range=[0.0, 1.05]),
width=600, height=500, # 调整大小以适应网页显示
legend=dict(x=0.6, y=0.1),
margin=dict(l=20, r=20, t=40, b=20) # 简洁边距
)
# 为了在网页环境中显示,您可以将 fig.to_json() 或 fig.to_html() 转换
# 对于此练习,我们将其表示为 JSON:
plotly_json = fig.to_json()
print("```plotly")
print(plotly_json)
print("```")
ROC 曲线示例,展示了真阳性率和假阳性率之间的权衡。蓝线表示分类器在不同阈值下的性能,而灰色虚线表示随机猜测。AUC 值总结了整体性能。
最佳指标完全取决于项目目标:
通过摆脱简单的准确度并使用精确率、召回率、F1分数和 AUC 等指标,您将对模型性能有更全面和可靠的认识。这些认识对于在模型选择、比较以及接下来讨论的超参数调整过程中做出明智的决定非常重要。
这部分内容有帮助吗?
© 2026 ApX Machine Learning用心打造