2、基础概念:混淆矩阵、TPR、FPR、精确率、召回率、F1-Score

好,咱们正式开始聊阈值调优。在动手调之前,有几个基础概念必须得先掰扯清楚。我见过不少新人,上来就调阈值,结果调了半天,业务指标一点没变,回头一问,连混淆矩阵是啥都说不利索。

说白了,这些概念就是风控模型的「体检报告」。看不懂报告,你怎么知道模型哪儿强、哪儿弱?

2.1 混淆矩阵:一切评估的起点

混淆矩阵,英文叫 Confusion Matrix。名字听着挺唬人,其实就是一个 2×2 的表格。它把模型的预测结果和真实情况做了个交叉对比。

对于一个二分类问题(比如:好客户 vs 坏客户),预测结果有四种情况:

  • 真正例(TP):实际是坏人,模型也判为坏人。抓对了。
  • 假正例(FP):实际是好人,模型误判为坏人。误伤了。
  • 假负例(FN):实际是坏人,模型漏判为好人。漏网了。
  • 真负例(TN):实际是好人,模型也判为好人。放对了。

嗯,这里要注意:「正例」通常指我们关注的那个类别。在风控里,我们关注的是「坏客户」,所以坏客户就是正例。这个定义别搞反了,我在项目里见过有人把好客户当正例,结果算出来的指标全反了,排查了半天才发现。

核心记忆点:

  • TP = 抓对了(坏人→坏人)
  • FP = 误伤了(好人→坏人)
  • FN = 漏网了(坏人→好人)
  • TN = 放对了(好人→好人)

咱们用一张图来直观感受一下这个矩阵的结构:

混淆矩阵结构图 真实:正例(坏人) 真实:负例(好人) 预测:正例(坏人) 预测:负例(好人) TP 真正例(抓对了) FP 假正例(误伤了) FN 假负例(漏网了) TN 真负例(放对了) 绿色=正确预测,红色/橙色=错误预测

2.2 TPR 与 FPR:模型的两把尺子

有了混淆矩阵,我们就可以算出各种比率了。我个人习惯,最先看的是 TPR 和 FPR。为什么?因为它们直接对应了风控最关心的两个问题:坏人抓得干不干净?好人误伤得多不多?

  • TPR(真正率 / 召回率) = TP / (TP + FN)
    说白了,就是「所有坏人里,模型抓出来了多少」。这个值越高越好,理想是 1.0。
  • FPR(假正率) = FP / (FP + TN)
    说白了,就是「所有好人里,模型误伤了多少」。这个值越低越好,理想是 0.0。

你想想看,TPR 和 FPR 是一对天生的冤家。阈值设得严,TPR 会下降(漏网变多),但 FPR 也会下降(误伤变少)。阈值设得松,TPR 上升(抓得干净),但 FPR 也上升(误伤变多)。

我的经验: 在信贷风控场景里,FPR 往往比 TPR 更敏感。因为误伤一个好客户,损失的是一笔利润;漏掉一个坏客户,损失的是一笔本金。具体哪个更重要,得看业务上坏账率和利润率怎么算。我建议你拿到数据后,先算一笔账:误伤一个好人亏多少,漏掉一个坏人亏多少,心里就有数了。

2.3 精确率与召回率:业务视角的权衡

精确率和召回率,这两个概念经常被混淆。我简单说一下区别:

  • 精确率(Precision) = TP / (TP + FP)
    含义是:模型判为坏人的那些人里,有多少是真的坏人?说白了就是「模型说你是坏人,你有多大概率真的是坏人」。
  • 召回率(Recall) = TP / (TP + FN)
    含义是:所有坏人里,模型找出来了多少?这个和 TPR 是同一个东西。

你看,精确率和召回率关注的视角不一样。精确率关心「别误伤」,召回率关心「别漏网」。在风控里,这两个指标往往是 trade-off 的关系。

举个例子:你把阈值设得极高,只有非常确定的坏人才拒绝。这时候精确率会很高(拒绝的人基本都是坏人),但召回率会很低(很多坏人没被拒掉)。反过来,阈值设得极低,稍微有点风险就拒绝,召回率会很高(坏人基本都被拒了),但精确率会很低(误伤了一堆好人)。

我曾经踩过的坑: 有一次做模型评估,只看精确率,觉得模型表现不错。结果上线后,坏账率反而上升了。排查后发现,召回率太低,大量坏人没被识别出来。所以,永远不要只看单一指标。精确率和召回率必须放在一起看。

2.4 F1-Score:一个折中的综合指标

既然精确率和召回率总是打架,那有没有一个指标能把它们综合起来?有,就是 F1-Score。

F1-Score 是精确率和召回率的调和平均数:

F1 = 2 × (Precision × Recall) / (Precision + Recall)

为什么用调和平均,而不是算术平均?因为调和平均对较小值更敏感。如果精确率很高但召回率很低,F1 也会很低。这正好符合我们的需求:我们希望两个指标都高,而不是一个高一个低。

举个例子:

  • 模型 A:精确率 0.9,召回率 0.1 → F1 = 2 × (0.9 × 0.1) / (0.9 + 0.1) = 0.18
  • 模型 B:精确率 0.5,召回率 0.5 → F1 = 2 × (0.5 × 0.5) / (0.5 + 0.5) = 0.50

你看,模型 B 虽然精确率低,但 F1 反而高,因为两个指标更均衡。

什么时候用 F1?

  • 当你需要找一个「平衡点」的时候,F1 是个好选择。
  • 但注意:如果业务上对精确率和召回率的重视程度不一样,F1 就不太合适了。这时候可以考虑 Fβ-Score,通过 β 参数来调整权重。

2.5 一张表总结所有指标

为了方便你查阅,我把这几个指标整理成了一张表:

指标 公式 关注点 理想值
TPR / 召回率 TP / (TP + FN) 坏人抓得干不干净 越高越好
FPR FP / (FP + TN) 好人误伤多不多 越低越好
精确率 TP / (TP + FP) 判为坏人的人里,多少是真的 越高越好
F1-Score 2PR / (P + R) 精确率与召回率的平衡 越高越好

2.6 用 Python 快速计算这些指标

理论讲完了,咱们来点实际的。我平时做风控模型评估,习惯用 scikit-learn 里的 metrics 模块,几行代码就能算出所有指标:

from sklearn.metrics import confusion_matrix, precision_score, recall_score, f1_score

# 假设 y_true 是真实标签,y_pred 是模型预测标签
y_true = [1, 0, 1, 1, 0, 1, 0, 0, 1, 0]
y_pred = [1, 0, 1, 0, 0, 1, 0, 1, 1, 0]

# 混淆矩阵
cm = confusion_matrix(y_true, y_pred)
print("混淆矩阵:")
print(cm)

# 精确率、召回率、F1
precision = precision_score(y_true, y_pred)
recall = recall_score(y_true, y_pred)
f1 = f1_score(y_true, y_pred)

print(f"精确率: {precision:.3f}")
print(f"召回率: {recall:.3f}")
print(f"F1-Score: {f1:.3f}")

# 手动计算 TPR 和 FPR
tn, fp, fn, tp = cm.ravel()
tpr = tp / (tp + fn)  # 召回率
fpr = fp / (fp + tn)

print(f"TPR (召回率): {tpr:.3f}")
print(f"FPR: {fpr:.3f}")

输出结果:

混淆矩阵:
[[3 1]
 [1 5]]
精确率: 0.833
召回率: 0.833
F1-Score: 0.833
TPR (召回率): 0.833
FPR: 0.250

小技巧: 注意 cm.ravel() 的顺序是 [TN, FP, FN, TP]。我第一次用的时候搞反了顺序,算出来的 TPR 和 FPR 全错了。建议你每次拿到混淆矩阵后,先打印出来看一眼,确认一下顺序。