Confusion Matrix
Perspective
Confusion matrix 是理解分类模型表现的第一张表。它不只告诉我们”模型对了多少”,还告诉我们模型把哪些类别混成了哪些类别。这比单独看一个 accuracy 更有诊断价值。
先记住一个实用边界:confusion matrix 只用于 classification,不用于 regression。 它比较的是真实类别和预测类别;如果目标变量 y 是连续数值,应该看 RMSE、MAE、R² 等回归指标。
Definition
A confusion matrix is a table that compares the predicted class labels with the true class labels of a classification model. In the usual layout, columns are predicted classes and rows are actual classes. Each cell counts how many observations fall into one actual-predicted combination.
中文理解:混淆矩阵是一张”预测类别 × 真实类别”的计数表。通常横向列是预测类别,纵向行是真实类别。对角线上的数字是预测正确的样本;非对角线上的数字是预测错误的样本,而且能看出错成了哪一类。
Why It Matters
分类模型的错误通常不是均匀分布的。一个模型可能整体 accuracy 很高,但在关键类别上表现很差。
比如医学筛查里,漏掉真正患病的人(false negative)通常比把健康人误报为可能患病(false positive)更严重。只看 accuracy 会把这两种错误混在一起;confusion matrix 会把它们拆开。
它主要回答三个问题:
- 模型总体分对了多少?
- 错误主要发生在哪些类别之间?
- 这些错误的代价是否一样?
Binary Classification
二分类时,通常把我们更关心的类别叫做 positive class,把另一类叫做 negative class。横向是预测类别,纵向是真实类别:
| Predicted Positive | Predicted Negative | |
|---|---|---|
| Actual Positive | TP | FN |
| Actual Negative | FP | TN |
四个格子的含义:
| 缩写 | 全称 | 中文理解 | 例子:疾病检测 |
|---|---|---|---|
| TP | True Positive | 真实是正类,预测也是正类 | 有病,预测有病 |
| TN | True Negative | 真实是负类,预测也是负类 | 没病,预测没病 |
| FP | False Positive | 真实是负类,却预测成正类 | 没病,误报有病 |
| FN | False Negative | 真实是正类,却预测成负类 | 有病,漏判没病 |
关键是:positive class 是人为指定的。 在疾病检测里,positive 通常是”有病”;在垃圾邮件检测里,positive 通常是”垃圾邮件”。不同 positive class 会改变 precision、recall 等指标的解释。
A Worked Example
假设一个疾病分类模型在 200 人上测试,结果如下:
| Predicted Disease | Predicted Healthy | |
|---|---|---|
| Actual Disease | 80 | 20 |
| Actual Healthy | 10 | 90 |
对应关系是:
| 数量 | 值 | 含义 |
|---|---|---|
| TP | 80 | 80 个真正有病的人被正确找出 |
| FN | 20 | 20 个真正有病的人被漏掉 |
| FP | 10 | 10 个健康人被误报为有病 |
| TN | 90 | 90 个健康人被正确排除 |
| Total | 200 | 总样本数 |
从这张表可以看出,模型一共错了 30 个样本:20 个漏诊,10 个误诊。对于医学场景,漏诊可能是更严重的问题,所以我们不能只看”错了 30 个”。
Metrics From the Matrix
很多分类指标都可以从 confusion matrix 直接计算出来。
| 指标 | 公式 | 这个指标在问什么 | 适合关注的场景 |
|---|---|---|---|
| Accuracy | (TP + TN) / Total |
总体有多少预测对了? | 类别比较平衡、错误代价相近 |
| Precision | TP / (TP + FP) |
预测为 positive 的样本里,有多少真的 positive? | 误报代价高,比如误封账号、误诊导致昂贵检查 |
| Recall / Sensitivity | TP / (TP + FN) |
真实 positive 里,有多少被找出来? | 漏报代价高,比如疾病筛查、风险预警 |
| Specificity | TN / (TN + FP) |
真实 negative 里,有多少被正确排除? | 需要避免把负类误判为正类 |
| F1-score | 2 * precision * recall / (precision + recall) |
precision 和 recall 的折中表现如何? | 类别不平衡、同时关心误报和漏报 |
套用上面的例子:
| 指标 | 计算 | 结果 | 解读 |
|---|---|---|---|
| Accuracy | (80 + 90) / 200 |
0.85 | 总体 85% 预测正确 |
| Precision | 80 / (80 + 10) |
0.889 | 预测有病的人里,88.9% 真的有病 |
| Recall | 80 / (80 + 20) |
0.800 | 真正有病的人里,80% 被找出来 |
| Specificity | 90 / (90 + 10) |
0.900 | 真正健康的人里,90% 被正确排除 |
| F1-score | 2 * 0.889 * 0.800 / (0.889 + 0.800) |
0.842 | precision 和 recall 的综合表现 |
Accuracy Can Mislead
当类别不平衡时,accuracy 很容易虚高。
假设 1000 人里只有 10 人有病。一个模型如果永远预测”没病”,它的 confusion matrix 是:
| Predicted Disease | Predicted Healthy | |
|---|---|---|
| Actual Disease | 0 | 10 |
| Actual Healthy | 0 | 990 |
它的 accuracy 是:
(0 + 990) / 1000 = 99%
但它的 recall 是:
0 / (0 + 10) = 0%
这个模型看起来有 99% accuracy,但完全找不出真正有病的人。所以在类别不平衡时,要特别看 recall、precision、F1、AUC,不能只看 accuracy。
Multi-Class Classification
多分类时,confusion matrix 仍然是横向预测类别、纵向真实类别,只是行列不止两个。
例如一个三分类模型预测肿瘤亚型 A、B、C:
| Predicted A | Predicted B | Predicted C | |
|---|---|---|---|
| Actual A | 42 | 5 | 3 |
| Actual B | 7 | 31 | 2 |
| Actual C | 4 | 6 | 50 |
读法:
- 对角线
42, 31, 50是分对的样本。 Actual A被预测成B有 5 个,被预测成C有 3 个。Actual C被预测成B有 6 个,说明模型可能容易混淆 C 和 B。
多分类里也可以计算每个类别的 precision 和 recall。做法是把某一个类别当作 positive,其他类别合并为 negative,然后逐类计算。
| 类别 | 这个类别的 recall 在问什么 | 这个类别的 precision 在问什么 |
|---|---|---|
| A | 真实 A 里,有多少被预测为 A? | 预测为 A 的样本里,有多少真实是 A? |
| B | 真实 B 里,有多少被预测为 B? | 预测为 B 的样本里,有多少真实是 B? |
| C | 真实 C 里,有多少被预测为 C? | 预测为 C 的样本里,有多少真实是 C? |
In Tidymodels
在 tidymodels 的 yardstick 里,conf_mat() 输出也是这个方向:列是预测值,行是真实值。
通常这样生成:
library(yardstick)
conf_mat(data = results, truth = actual_class, estimate = predicted_class)其中 truth 是真实标签,对应表格的行;estimate 是预测标签,对应表格的列。
Key Points
- Confusion matrix 是分类模型的”预测类别 × 真实类别”计数表,通常列是预测类别、行是真实类别。
- 对角线是预测正确;非对角线是预测错误,并且能看出错成哪一类。
- 二分类里常用 TP、TN、FP、FN 描述四种结果。
- Accuracy 看整体正确率,但在类别不平衡时可能严重误导。
- Precision 关注”预测为正类的结果有多可信”;recall 关注”真实正类有多少被找出来”。
- False positive 和 false negative 的实际代价常常不同,评价模型时要结合具体问题。
- 多分类 confusion matrix 可以看类别之间的混淆模式,也可以逐类计算 precision 和 recall。
- 读表时先看列名和行名:横向 predicted,纵向 actual。
Reading Checks
读到一个分类模型的结果时,可以按这个顺序问:
- 这是 classification 任务吗?如果是 regression,就不该用 confusion matrix。
- Confusion matrix 是否按横向 predicted、纵向 actual 来读?
- Positive class 是哪一个?这个选择是否符合研究问题?
- 错误主要集中在哪些格子?是 false positive 多,还是 false negative 多?
- 类别是否不平衡?如果不平衡,作者是否只报了 accuracy?
- 这个场景里,误报和漏报的代价是否一样?如果不一样,应该优先看 precision 还是 recall?
- 多分类时,哪些类别最容易互相混淆?这种混淆在领域上是否合理?
Note
对我来说,confusion matrix 最有用的地方是它把”模型错了”拆成了具体错误类型。很多时候真正的问题不是模型准确率低,而是它在关键类别上犯了不能接受的错。读分类模型时,先看这张表,再看衍生指标,判断会稳很多。
Sources
- Kuhn & Silge, Tidy Modeling with R
- Kuhn & Johnson, Applied Predictive Modeling
- Hastie, Tibshirani & Friedman, The Elements of Statistical Learning