# 题目重述
根据提供的 CSV 文件 `confusion_matrix.csv` 中的混淆矩阵数据,使用 Python 绘制混淆矩阵热力图,并计算以下指标:True Positive (TP)、False Positive (FP)、True Negative (TN)、False Negative (FN)、Accuracy、Precision、Recall、Specificity、F1-Score,同时绘制 ROC 曲线并计算 AUC 值,展示完整的算法实现过程。
---
# 详解
### ✅ 步骤 1:读取数据并构建混淆矩阵
```python
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.metrics import roc_curve, auc
from itertools import cycle
# 读取CSV文件
df = pd.read_csv('confusion_matrix.csv', index_col=0)
matrix = df.values
classes = df.index.tolist()
print("混淆矩阵:")
print(df)
```
输出:
```
0a 3a 4a 5a
0a 81 5 3 0
3a 0 68 3 0
4a 10 8 9 34
5a 8 0 9 50
```
---
### ✅ 步骤 2:绘制混淆矩阵热力图
```python
plt.figure(figsize=(8, 6))
sns.heatmap(matrix, annot=True, fmt='d', cmap='Blues', xticklabels=classes, yticklabels=classes)
plt.title('Confusion Matrix')
plt.xlabel('Predicted Label')
plt.ylabel('True Label')
plt.show()
```
---
### ✅ 步骤 3:逐类计算 TP, FP, TN, FN
对于多分类问题,采用**一对多(One-vs-Rest)**策略逐类计算:
```python
n_classes = matrix.shape[0]
metrics = {}
for i in range(n_classes):
tp = matrix[i, i]
fp = matrix[:, i].sum() - tp
fn = matrix[i, :].sum() - tp
tn = matrix.sum() - tp - fp - fn
accuracy = (tp + tn) / matrix.sum()
precision = tp / (tp + fp) if (tp + fp) > 0 else 0
recall = tp / (tp + fn) if (tp + fn) > 0 else 0
specificity = tn / (tn + fp) if (tn + fp) > 0 else 0
f1 = 2 * precision * recall / (precision + recall) if (precision + recall) > 0 else 0
metrics[classes[i]] = {
'TP': tp,
'FP': fp,
'TN': tn,
'FN': fn,
'Accuracy': accuracy,
'Precision': precision,
'Recall': recall,
'Specificity': specificity,
'F1-Score': f1
}
```
打印结果示例:
```python
for cls, metric in metrics.items():
print(f"\n--- Class {cls} ---")
for k, v in metric.items():
if isinstance(v, float):
print(f"{k}: {v:.4f}")
else:
print(f"{k}: {v}")
```
---
### ✅ 步骤 4:绘制 ROC 曲线 和 计算 AUC(多分类扩展)
由于是多分类问题,我们使用 OvR(One-vs-Rest)方式近似 ROC 和 AUC。这里假设我们有预测概率(但原文件只有混淆矩阵)。
⚠️ **注意:从混淆矩阵无法还原原始预测概率,因此无法精确绘制 ROC 曲线或计算 AUC。**
但我们可以通过**模拟方法演示流程**(假设有预测分数):
```python
# 模拟真实标签和预测分数(仅用于演示)
from sklearn.preprocessing import label_binarize
# 假设真实标签和预测得分(举例说明)
y_true = []
y_score = []
# 构造模拟数据以匹配混淆矩阵分布(简化处理)
mapping = {'0a': 0, '3a': 1, '4a': 2, '5a': 3}
inv_mapping = {v: k for k, v in mapping.items()}
y_true.extend([0]*81 + [1]*71 + [2]*61 + [3]*67) # 总样本数对应每行sum
np.random.seed(42)
# 构造带噪声的预测分数(越接近正确类别得分越高)
for true_label in y_true:
score = np.random.randn(4) * 0.5
score[true_label] += 1.0 # 正确类别的得分偏高
y_score.append(score)
y_score = np.array(y_score)
y_true_bin = label_binarize(y_true, classes=[0,1,2,3])
# 计算每个类别的ROC曲线和AUC
fpr = dict()
tpr = dict()
roc_auc = dict()
plt.figure(figsize=(8, 6))
colors = cycle(['aqua', 'darkorange', 'cornflowerblue', 'red'])
for i, color in zip(range(n_classes), colors):
fpr[i], tpr[i], _ = roc_curve(y_true_bin[:, i], y_score[:, i])
roc_auc[i] = auc(fpr[i], tpr[i])
plt.plot(fpr[i], tpr[i], color=color, lw=2,
label=f'ROC curve of class {inv_mapping[i]} (AUC = {roc_auc[i]:.2f})')
plt.plot([0, 1], [0, 1], 'k--', lw=2)
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Multi-class ROC Curve (One-vs-Rest)')
plt.legend(loc="lower right")
plt.grid(True)
plt.show()
print("AUC Scores:")
for i in range(n_classes):
print(f"Class {inv_mapping[i]}: AUC = {roc_auc[i]:.4f}")
```
> 🔔 **重要提示**:实际中,若仅有混淆矩阵,**不能可靠地绘制 ROC 或计算 AUC**,因为缺少预测置信度信息。
---
# 知识点(列出解答该问题需要的知识点)
- **混淆矩阵与分类指标计算**:通过TP、FP等定义推导Precision、Recall等指标,适用于评估分类性能。
- **多分类ROC与AUC**:采用OvR策略将多类问题转为多个二分类问题,分别计算ROC和AUC。
- **Seaborn热力图可视化**:利用`sns.heatmap()`直观展示混淆矩阵中各类别的预测分布情况。