模型评估与选择进阶20 分钟kp-026#类不平衡#代价敏感#重采样

不平衡数据与代价敏感学习

进度

一句话定义

类别不平衡(少数类占比悬殊)会让以均值为优化目标的标准训练系统性偏袒多数类;对策有三层——数据层重采样、算法层代价敏感(类权重)、决策层阈值调整,选择依据是错误的业务代价与数据规模。

为什么重要

欺诈检测、罕见病筛查、设备故障预测、流失预警——高价值问题里少数类才是主角。不平衡不只是「指标难看」:损失函数按样本均摊,少数类梯度贡献微弱,模型真的学不会少数类;处理不当的调参方向还会与业务目标背道而驰。

前置知识

分类评估指标:混淆矩阵、Precision/Recall 与 ROC-AUC 的 P/R 与阈值视角;损失函数:从 0-1 损失到代理损失 的损失按样本累加结构。

核心概念

  • 不平衡比:多数类 : 少数类的样本量之比。
  • 随机欠采样:丢多数类样本,快但丢信息;随机过采样:复制少数类,快但过拟合风险高。
  • SMOTE:在少数类近邻连线上插值造新样本,缓解简单复制的过拟合(对高维与噪声敏感)。
  • 类权重:损失中给少数类样本乘权重 wc ∝ nK nc,等价于把「代价」写进训练。
  • 阈值移动:训练不动,预测时调低正类阈值换召回。
  • 代价矩阵:cFP, cFN 显式定价两类错误,一切权衡的锚。

直观类比

阅卷标准:一份卷子 97% 的题目是送分题、3% 是拉分题。按总分(总准确率)评价,学生放弃所有拉分题也能 97 分。要让老师认真教拉分题,要么「拉分题每道按 30 分计」(类权重/重采样),要么「及格线看拉分题得分」(阈值移动)——三条路都是重新分配「注意力」。

原理与机制

标准经验风险 1n∑i Li 中少数类贡献占比仅为其样本占比,梯度信号微弱,多数类主导决策边界。类权重把目标改为 1n∑i wyi Li,w 与类频率成反比,等价于把经验分布重加权到「均衡分布」上——统计意义上是从 P(x, y) 下的学习切换到 P(x | y) 加权(一种简单的重要性加权)。过采样显式改变经验分布,效果与加权相似但改变样本空间(SMOTE 的插值 xnew = xi + u(xzn - xi), u ∼ U(0,1) 还引入了「少数类流形内部连续」的先验假设,在类间重叠区会造出模糊样本)。阈值移动不改模型只改决策:贝叶斯决策理论指出最优阈值由代价比决定(cFNcFP + cFN 的函数),概率校准良好时它是零成本的实现路径。三层手段可以叠加,但都必须在训练区内做、用 PR 类指标评估(kp-023 的结论)。

公式与推导

代价敏感的贝叶斯最优决策:预测正类当且仅当期望代价更小,即

cFN · p ≤ cFP · (1 - p)  ⟺  p ≥ cFPcFP + cFN ≡ t^*

推导:E[cost | ŷ=1] = cFP(1 - p),E[cost | ŷ=0] = cFN · p,比较两者即得。注意 t^* 只依赖代价比、不依赖类别频率——「按频率调阈值」与「按代价调阈值」是两件事,混淆它们是不平衡调参最常见的错误。

图示

样本空间(○多数类 ×少数类)
 ○○○○○○○○○○○○○○○        随机过采样:×被复制 → 边界贴死
 ○○○○ ×× ○○○○○○○         SMOTE:×× 之间插值造 ×′ → 边界更泛化
 ○○○○×′××○○○○○○○          类权重:不造样本,让 × 的梯度×30
 ○○○○○○○○○○○○○○○          阈值移动:模型不动,只在判决处松口

实例或案例

三种手段在 1:50 数据上的对照(评估用 PR-AUC 与少数类 F1):

from sklearn.datasets import make_classification
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_validate
from sklearn.metrics import make_scorer, f1_score, average_precision_score

X, y = make_classification(n_samples=5000, weights=[0.98, 0.02], random_state=0)
scoring = {"PR-AUC": "average_precision", "F1少": make_scorer(f1_score, pos_label=1)}
for name, m in {
    "原样":        LogisticRegression(max_iter=2000),
    "类权重":      LogisticRegression(max_iter=2000, class_weight="balanced"),
    "少数类×10":   LogisticRegression(max_iter=2000, class_weight={0: 1, 1: 10}),
}.items():
    r = cross_validate(m, X, y, cv=5, scoring=scoring)
    print(f"{name:>8}: PR-AUC={r['test_PR-AUC'].mean():.3f} F1={r['test_F1少'].mean():.3f}")

类权重显著提升少数类 F1,PR-AUC 提升幅度因模型与数据而异——最终选择必须回到代价矩阵。

常见误区

  • 在测试集/验证集上做重采样:评估分布必须保持真实;重采样只发生在训练折。
  • 先过采样再划分:少数类合成样本的「兄弟」跨进训练与验证,泄漏式虚高(kp-025 的变体)。
  • 用准确率对比方案优劣:必须换 PR-AUC / F1 / 召回@精确率。
  • 把 SMOTE 当默认解:高维稀疏(文本 one-hot)或类间重叠严重时插值样本质量差,类权重往往更稳。

与其他知识点的关系

分类评估指标:混淆矩阵、Precision/Recall 与 ROC-AUC 提供评估语言;正则化:岭回归、Lasso 与弹性网 的加权思想(样本权重 = 另一种正则)同源;Boosting 与 AdaBoost 的 AdaBoost 在极端不平衡下会被多数类淹没,需配合权重;公平性、可复现性与机器学习伦理 的公平性问题中,「把少数群体当少数类处理」正是需要警惕的粗糙做法。

自测题

  1. 类权重与随机过采样在统计效果上的关系?

- 要点:都是把有效经验分布推向均衡;加权不改变样本集、过采样会因复制/插值引入过拟合或人工样本,工程上加权更轻量。

  1. 最优阈值公式及其含义?

- 要点:t^* = cFPcFP + cFN,只由代价比决定;与类别频率无关,频率影响的是概率估计本身。

  1. 为什么重采样必须在训练区内做?

- 要点:验证/测试分布要反映真实部署分布;合成样本跨越划分还会造成近邻泄漏,评估失真。

延伸阅读

He & Garcia, Learning from Imbalanced Data(IEEE TKDE, 2009);周志华《机器学习》第 2.3.5、7.6 节。