深度学习评估指标实战:混淆矩阵与5大核心指标(Accuracy/Precision/Recall/F1/AUC)代码解析
深度学习评估指标实战:混淆矩阵与5大核心指标代码解析
在深度学习分类任务中,训练出一个模型只是第一步,如何科学评估模型性能才是关键。本文将带您用Python代码实现混淆矩阵及Accuracy、Precision、Recall、F1-Score、AUC这5个核心指标的计算与可视化,并针对类别不平衡场景给出专业解读建议。
1. 环境准备与数据加载
首先确保已安装必要的Python库。推荐使用conda创建虚拟环境:
conda create -n metrics python=3.8
conda activate metrics
pip install numpy pandas matplotlib scikit-learn seaborn
我们以经典的乳腺癌数据集为例,该数据集包含569个样本,30个特征,目标变量为恶性(1)与良性(0)两类:
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
data = load_breast_cancer()
X, y = data.data, data.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
训练一个简单的随机森林分类器作为演示模型:
from sklearn.ensemble import RandomForestClassifier
model = RandomForestClassifier(n_estimators=100, random_state=42)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
y_proba = model.predict_proba(X_test)[:, 1] # 获取正类的预测概率
2. 混淆矩阵的代码实现与解读
混淆矩阵是理解分类模型性能的基础工具。使用sklearn的confusion_matrix函数:
from sklearn.metrics import confusion_matrix
import seaborn as sns
import matplotlib.pyplot as plt
def plot_confusion_matrix(y_true, y_pred, classes):
cm = confusion_matrix(y_true, y_pred)
plt.figure(figsize=(6, 6))
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues',
xticklabels=classes, yticklabels=classes)
plt.xlabel('Predicted')
plt.ylabel('Actual')
plt.title('Confusion Matrix')
plt.show()
plot_confusion_matrix(y_test, y_pred, classes=['Benign', 'Malignant'])
混淆矩阵中的四个关键数值:
- TP (True Positive) :实际为正且预测为正的样本数
- FP (False Positive) :实际为负但预测为正的样本数
- FN (False Negative) :实际为正但预测为负的样本数
- TN (True Negative) :实际为负且预测为负的样本数
提示:在医疗诊断场景中,FN(漏诊)通常比FP(误诊)后果更严重,需要特别关注召回率指标
3. 五大核心指标的计算与可视化
3.1 Accuracy(准确率)
准确率是最直观的指标,表示正确预测的比例:
from sklearn.metrics import accuracy_score
accuracy = accuracy_score(y_test, y_pred)
print(f"Accuracy: {accuracy:.4f}")
# 手动计算公式
def manual_accuracy(y_true, y_pred):
cm = confusion_matrix(y_true, y_pred)
return (cm[0,0] + cm[1,1]) / cm.sum()
适用场景 :各类别样本均衡时效果良好,但在类别不平衡数据上会失真。例如在99%负样本的数据集中,全预测为负也能获得99%准确率。
3.2 Precision(精确率)
精确率关注预测为正的样本中有多少是真的正例:
from sklearn.metrics import precision_score
precision = precision_score(y_test, y_pred)
print(f"Precision: {precision:.4f}")
# 手动计算公式
def manual_precision(y_true, y_pred):
cm = confusion_matrix(y_true, y_pred)
return cm[1,1] / (cm[1,1] + cm[0,1])
业务意义 :在垃圾邮件分类中,高精确率意味着用户收件箱中真正的垃圾邮件比例高。
3.3 Recall(召回率)
召回率关注实际为正的样本中有多少被正确预测:
from sklearn.metrics import recall_score
recall = recall_score(y_test, y_pred)
print(f"Recall: {recall:.4f}")
# 手动计算公式
def manual_recall(y_true, y_pred):
cm = confusion_matrix(y_true, y_pred)
return cm[1,1] / (cm[1,1] + cm[1,0])
业务意义 :在癌症筛查中,高召回率意味着尽可能少地漏诊真实患者。
3.4 F1-Score
F1-Score是精确率和召回率的调和平均数,适用于需要平衡两者的场景:
from sklearn.metrics import f1_score
f1 = f1_score(y_test, y_pred)
print(f"F1-Score: {f1:.4f}")
# 手动计算公式
def manual_f1(y_true, y_pred):
p = manual_precision(y_true, y_pred)
r = manual_recall(y_true, y_pred)
return 2 * p * r / (p + r)
应用场景 :在信息检索系统中,既希望返回的结果尽可能相关(高精确率),又希望尽可能多的相关结果被返回(高召回率)。
3.5 AUC-ROC曲线
AUC-ROC曲线衡量模型区分正负样本的能力:
from sklearn.metrics import roc_curve, auc
fpr, tpr, thresholds = roc_curve(y_test, y_proba)
roc_auc = auc(fpr, tpr)
plt.figure(figsize=(8, 6))
plt.plot(fpr, tpr, color='darkorange', lw=2,
label=f'ROC curve (AUC = {roc_auc:.2f})')
plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver Operating Characteristic')
plt.legend(loc="lower right")
plt.show()
解读要点 :
- AUC=0.5:模型无区分能力
- 0.7<AUC<0.8:有一定区分能力
- 0.8<AUC<0.9:区分能力良好
- AUC>0.9:区分能力优秀
4. 类别不平衡场景下的指标选择
当数据存在严重类别不平衡时,需要特别谨慎选择评估指标。以信用卡欺诈检测为例(正常交易占99.9%,欺诈占0.1%):
| 指标 | 适用性 | 原因 |
|---|---|---|
| Accuracy | 不推荐 | 会被多数类主导 |
| Precision | 中等 | 关注预测为欺诈的交易质量 |
| Recall | 重要 | 尽可能捕捉所有真实欺诈 |
| F1-Score | 推荐 | 平衡精确率和召回率 |
| AUC-ROC | 推荐 | 不受类别分布影响 |
处理类别不平衡的实用技巧:
- 使用class_weight参数调整类别权重
- 采用过采样(SMOTE)或欠采样技术
- 选择PR曲线替代ROC曲线
- 设置合理的决策阈值(非默认0.5)
# 调整决策阈值示例
from sklearn.metrics import precision_recall_curve
precisions, recalls, thresholds = precision_recall_curve(y_test, y_proba)
plt.plot(thresholds, precisions[:-1], 'b--', label='Precision')
plt.plot(thresholds, recalls[:-1], 'g-', label='Recall')
plt.xlabel('Threshold')
plt.legend(loc='center left')
plt.title('Precision-Recall Tradeoff')
plt.show()
5. 完整评估模块封装
将上述功能封装成可复用的评估类:
class ClassificationEvaluator:
def __init__(self, y_true, y_pred, y_proba=None):
self.y_true = y_true
self.y_pred = y_pred
self.y_proba = y_proba
self.cm = confusion_matrix(y_true, y_pred)
def plot_confusion_matrix(self, classes):
plt.figure(figsize=(6, 6))
sns.heatmap(self.cm, annot=True, fmt='d', cmap='Blues',
xticklabels=classes, yticklabels=classes)
plt.xlabel('Predicted')
plt.ylabel('Actual')
plt.title('Confusion Matrix')
plt.show()
def calculate_metrics(self):
metrics = {
'accuracy': accuracy_score(self.y_true, self.y_pred),
'precision': precision_score(self.y_true, self.y_pred),
'recall': recall_score(self.y_true, self.y_pred),
'f1': f1_score(self.y_true, self.y_pred)
}
if self.y_proba is not None:
fpr, tpr, _ = roc_curve(self.y_true, self.y_proba)
metrics['auc'] = auc(fpr, tpr)
return metrics
def plot_roc_curve(self):
if self.y_proba is None:
raise ValueError("y_proba is required for ROC curve")
fpr, tpr, _ = roc_curve(self.y_true, self.y_proba)
roc_auc = auc(fpr, tpr)
plt.figure(figsize=(8, 6))
plt.plot(fpr, tpr, color='darkorange', lw=2,
label=f'ROC curve (AUC = {roc_auc:.2f})')
plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver Operating Characteristic')
plt.legend(loc="lower right")
plt.show()
# 使用示例
evaluator = ClassificationEvaluator(y_test, y_pred, y_proba)
evaluator.plot_confusion_matrix(['Benign', 'Malignant'])
print(evaluator.calculate_metrics())
evaluator.plot_roc_curve()
在实际项目中,这套评估模块可以帮助您快速诊断模型表现。记得在医疗、金融等高风险领域,除了这些量化指标,还需要结合业务场景设计专门的评估方案。
更多推荐

所有评论(0)