第2章:混淆矩阵——TP、TN、FP、FN的定义与计算

聊分类模型评估,你第一个要搞清楚的,就是混淆矩阵。

说白了,它就是一张表。这张表能告诉你,你的模型到底在哪些地方做对了,又在哪些地方做错了。我刚开始做机器学习那会儿,觉得看个准确率就够了。直到有一次,我训练一个猫狗分类器,准确率90%多,我高兴坏了,结果一部署到线上,发现模型把大部分的猫都认成了狗。

为什么会这样?就因为样本不平衡。猫的图片太少,狗的图片太多。模型只要把所有图片都猜成狗,准确率就很“漂亮”。但这样模型根本没用。后来我养成了一个习惯:无论什么分类任务,先打印混淆矩阵,看看再说。

2.1 四个基本概念:TP、TN、FP、FN

混淆矩阵是2x2的方阵,对应二分类问题中的四种预测结果。我们得先定义一下,什么叫“正类(Positive)”和“负类(Negative)”。

通常,我们把关注的、相对稀少的类别称为正类(比如“有病”、“是猫”、“欺诈”),另一类就是负类。这个划分其实挺关键的,我在项目中遇到过团队因为正负类定义不统一,导致评估结果完全对不上的情况。

注意:正负类的定义直接影响所有后续指标。定义要提前对齐,别等到评估的时候才发现问题。
  • 真正例(TP - True Positive):模型预测为正类,实际上也是正类。猜对了,且猜的是正类。
  • 真负例(TN - True Negative):模型预测为负类,实际上也是负类。猜对了,且猜的是负类。
  • 假正例(FP - False Positive):模型预测为正类,但实际上它是负类。这就是“误报”。模型把负样本当成了正样本。
  • 假负例(FN - False Negative):模型预测为负类,但实际上它是正类。这就是“漏报”。模型把正样本漏掉了。

你想想看,FP和FN是两个最重要的错误类型。在不同业务场景下,它们的代价完全不同。

2.2 举个例子,更好理解

假设我们有100个样本,其中30个是猫,70个是狗。我们训练了一个猫狗分类器,目标是“找出猫”。所以,猫就是正类(Positive)。

模型预测的结果如下:

实际\预测 预测为猫(正类) 预测为狗(负类)
实际是猫(正类) TP = 25(猜对了,是猫) FN = 5(猜错了,把猫说成狗)
实际是狗(负类) FP = 10(猜错了,把狗说成猫) TN = 60(猜对了,是狗)

这个例子很清晰吧?TP=25,表示有25只猫被正确识别。FN=5,有5只猫被漏掉了,误判为狗。FP=10,有10只狗被误报为猫。TN=60,有60只狗被正确识别。

2.3 如何计算?

其实计算很简单,就是从混淆矩阵里把四个数值拿出来。

我用Python的sklearn举例子,你可以在代码里直接调用:

from sklearn.metrics import confusion_matrix

# 假设 y_true 是真实标签,y_pred 是模型预测结果
y_true = [1, 0, 1, 1, 0, 1, 0, 0, 1, 0]  # 1代表猫,0代表狗
y_pred = [1, 0, 1, 0, 0, 1, 0, 0, 0, 1]

# 生成混淆矩阵
cm = confusion_matrix(y_true, y_pred)
print(cm)

# 输出结果类似:
# [[TN FP]
#  [FN TP]]
# 注意sklearn的矩阵是TN、FP、FN、TP的顺序,别搞反了。

你可能注意到了,sklearn返回的矩阵顺序是:第一行是负类,第二行是正类。这一点我以前踩过坑,每次都得确认一遍。

如果你想手动计算:

TP = sum((y_true == 1) & (y_pred == 1))
TN = sum((y_true == 0) & (y_pred == 0))
FP = sum((y_true == 0) & (y_pred == 1))
FN = sum((y_true == 1) & (y_pred == 0))

2.4 矩阵可视化

光看数字太抽象,一般我们会把混淆矩阵画出来。画成热力图,一眼就能看出模型的“盲区”。

下面这个SVG图,展示了混淆矩阵的核心逻辑和结构与流程:

混淆矩阵核心逻辑 & 流程 实际标签 正类 (P) 负类 (N) 预测标签 正类 (P) 负类 (N) TP (正→正) FN (正→负) TP: 猜对了对象是目标 | TN: 猜对了对象不是目标 FP: 误报了(把非目标当成目标) | FN: 漏报了(把目标当成非目标)

2.5 我的一些经验与避坑指南

我曾经在一个医疗影像的癌症检测项目里,只用accuracy作为评估指标。模型性能看起来不错,但医生们说没啥用。我打印了混淆矩阵一看,大吃一惊:模型几乎把所有阴性样本(没病)都预测对了,但阳性样本(有病)的召回率极低。说白了,这个模型漏掉了大部分病人。这要是上线,后果不堪设想。这就是混淆矩阵的价值所在。

你想想看,如果没有混淆矩阵,单纯看准确率,你很难发现这种“模型偷懒”的现象。我建议你在任何分类任务中,都把混淆矩阵作为第一个输出的评估结果。

  • 避坑1:我之前写代码混淆矩阵的顺序搞反过,拿TN当成了TP。多亏画图出来颜色不对,才及时发现。
  • 避坑2:对于多分类问题(比如猫、狗、鸟三种),混淆矩阵会变成3x3,但核心逻辑一样:行是真实标签,列是预测标签。对角线是正确分类,其他位置是错误分类。
一个小技巧:用热力图可视化混淆矩阵。颜色越深,数值越大。这样一眼就能看出模型在哪些类别之间容易混淆(比如,把猫和狗都认成狗,那对应格子的颜色就会很浅)。

好了,混淆矩阵的四个基本元素就讲到这里了。它不仅仅是四个数字,更是我们理解模型行为的第一步。