2、基础概念:混淆矩阵、TPR、FPR、精确率、召回率、F1-Score
好,咱们正式开始聊阈值调优。在动手调之前,有几个基础概念必须得先掰扯清楚。我见过不少新人,上来就调阈值,结果调了半天,业务指标一点没变,回头一问,连混淆矩阵是啥都说不利索。
说白了,这些概念就是风控模型的「体检报告」。看不懂报告,你怎么知道模型哪儿强、哪儿弱?
2.1 混淆矩阵:一切评估的起点
混淆矩阵,英文叫 Confusion Matrix。名字听着挺唬人,其实就是一个 2×2 的表格。它把模型的预测结果和真实情况做了个交叉对比。
对于一个二分类问题(比如:好客户 vs 坏客户),预测结果有四种情况:
- 真正例(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 全错了。建议你每次拿到混淆矩阵后,先打印出来看一眼,确认一下顺序。