现实中,样本(类别)样本不平衡(class-imbalance)是一种常见的现象,如:金融欺诈交易检测,欺诈交易的订单样本通常是占总交易数量的极少部分,而且对于有些任务而言少数样本更为重要。一般地,样本类别比例(Imbalance Ratio)(多数类vs少数类)严重不平衡时,分类算法将开始做出有利于多数类的预测。
一文解决样本不均衡(全)
数据抽样
随机抽样(random sampling)在机器学习领域,是很常见的做法。例如,将原始数据集随机分为训练集和测试集。常用的抽样方法有无放回抽样和有放回抽样。
针对非平衡的数据集,为了使得模型在这个数据集上学习的效果更加好,通过减少分类中多数类样本的数量(欠采样)或者增加分类中少数类样本的数量(过采样),来实现样本均衡。
过采样(over sampling)和欠采样(under sampling)也叫做上采样和下采样。
SMOTE是一种合成少数类过采样技术,主要策略为
- 首先,对每个少数类样本 x i \mathbf x_i xi,从它的最近邻中随机选 k k k 个样本;
- 然后,在 x i \mathbf x_i xi和近邻样本之间的连线上随机选一点作为新合成的少数类样本。
除了常用的smote之外,还有自适应合成采样,比如Borderline-SMOTE、Adaptive Synthetic Sampling(ADA-SYN)等,都包含在 imblearn Python 库中。
数据增强
数据增强(Data Augmentation)是指从原始数据中加工出更多的数据表示,提高原数据的数量和质量,从而提高模型的学习效果。
基于样本变换的数据增强
- 单样本增强:主要用于图像,比如几何操作、颜色变换、随机查出、剪切旋转等等,可参见imgaug开源库。
- 多样本增强:是指通过组合及转换多个样本的方式,比如刚刚提到的smote,还有SamplePairing、Mixup等方法在特征空间内构造已知样本的邻域值样本。
基于深度学习的数据增强
生成模型,如变分自编码网络(VAE)和生成生成对抗网络(GAN),其生成样本的方法也可以用于数据增强,这种基于网络合成的方法相比于传统的数据增强技术虽然过程复杂,但是生成的样本更加多样。
损失函数
损失函数层面的主流就是常用的代价敏感(cost-sensitive)学习,为不同的分类错误给予不同惩罚力度(权重),在调解类别平衡的同时,也不会增加计算复杂度。即对少数类样本给更大的权重系数,对多数类样本给更小的权重系数,通过这种方式可以在一定程度上解决样本不均衡的问题。
class weight 可以为不同类别的样本提供不同的权重,少数类的样本有更高的权重,从而模型可以平衡各类别的学习。如sklearn提供的class_weight参数,可以作为超参调试,避免决策边界偏重多数类的现象。
OHEM(Online Hard Example Mining)算法的核心是选择一些难样本(多样性和高损失的样本)作为训练的样本,针对性地改善模型学习效果。对于数据的类别不平衡问题,OHEM的针对性更强。
Focal loss的核心思想是在交叉熵损失函数(CE)的基础上增加了类别的不同权重以及困难(高损失)样本的权重(如下公式),以改善模型学习效果。
Focal Loss的核心思想是在交叉熵损失函数(CE)的基础上增加了类别的不同权重以及困难(高损失)样本的权重,以改善模型学习效果。
对于二元分类问题,交叉熵(cross entropy)损失函数定义为
CE ( p t ) = − log p t \text{CE}(p_t)=-\log p_t CE(pt)=−logpt
其中 P t P_t Pt 为正样本概率函数,用来简化公式:
p t = { p if y = 1 1 − p otherwise p_t=\begin{cases} p & \text{if } y=1 \\ 1-p & \text{otherwise} \end{cases} pt={p1−pif y=1otherwise
Focal Loss 函数定义如下:
FL ( p t ) = − a t ( 1 − p t ) γ log p t \text{FL}(p_t)=-a_t(1-p_t)^{\gamma}\log p_t FL(pt)=−at(1−pt)γlogpt
其中权重因子 a t a_t at 根据正负样本的分布设置,用来平衡损失函数分布
a t = { a if y = 1 1 − a otherwise a_t=\begin{cases} a & \text{if } y=1 \\ 1-a & \text{otherwise} \end{cases} at={a1−aif y=1otherwise
( 1 − p t ) γ (1-p_t)^{\gamma} (1−pt)γ 称为调制因子(modulating factor),
分解开来
FL ( p t ) = a t ( 1 − p t ) γ CE ( p t ) = { − a ( 1 − p ) γ log p if y = 1 − ( 1 − a ) p γ log ( 1 − p ) otherwise \text{FL}(p_t)=a_t(1-p_t)^{\gamma}\text{CE}(p_t) =\begin{cases} -a(1-p)^{\gamma}\log p & \text{if }y=1 \\ -(1-a)p^{\gamma}\log(1-p) & \text{otherwise} \end{cases} FL(pt)=at(1−pt)γCE(pt)={−a(1−p)γlogp−(1−a)pγlog(1−p)if y=1otherwise
调制因子减少了易于分类(概率高)的样本的贡献。
- 当 p t → 0 p_t\to 0 pt→0 的时候,调制因子趋于1,对于总的loss的贡献很大。当 p t → 1 p_t\to 1 pt→1的时候,调制因子趋于0,也就是对于总的loss的贡献很小。
- 当 γ = 0 \gamma=0 γ=0 的时候,focal loss就是传统的交叉熵损失,可以通过调整 γ \gamma γ 实现调制因子的改变。
引用作者的话:当 γ = 2 \gamma=2 γ=2 时,与 CE 相比,分类为 p t = 0.9 p_t = 0.9 pt=0.9 的示例的损失将降低 100 倍,而当 p t ≈ 0.968 p_t ≈ 0.968 pt≈0.968 时,其损失将降低 1000 倍。减少易于分类的示例的损失,可以让训练更多地关注难以分类的示例。
模型层面
解决不均衡问题,更为优秀的是基于采样+集成树模型等方法,可以在类别不均衡数据上表现良好。采样+集成学习这类方法简单来说,通过重复组合少数类样本与抽样的同样数量的多数类样本,训练若干的分类器进行集成学习。
EasyEnsemble 是利用模型集成(Ensemble)的方法多次欠采样。核心思路就是将多数类样本集随机分成 N 个子集,且每一个子集样本与少数类样本相同,然后分别将各个多数类样本子集与少数类样本进行组合,产生多个不同的训练集,进而训练多个不同的基分类器,最后bagging集成各基分类器,得到最终模型。
BalanceCascade 是利用增量训练的思想(Boosting)。核心思路就是在每一轮训练时都使用多数类与少数类数量上相等的训练集,然后使用该分类器对全体多数类进行预测,对于那些分类正确的多数类样本不放回,然后对这个更小的多数类样本欠采样产生训练集,然后进入下一轮迭代继续降低多数类数量。
通常,在数据集噪声较小的情况下,可以用BalanceCascade,可以用较少的基分类器数量得到较好的表现(基于串行的集成学习方法,对噪声敏感容易过拟合)。噪声大的情况下,可以用EasyEnsemble,基于串行+并行的集成学习方法,bagging多个Adaboost过程可以抵消一些噪声影响。
评估指标
分类常用的指标precision、recall、F1、混淆矩阵,对于样本不均衡的不同程度,都会明显改变这些指标的表现。可以采用AUC、AUPRC(更优)评估模型表现,AUC对样本的正负样本比例情况是不敏感。