类别不均衡

"trick"

Posted by zwt on July 28, 2022

带来的问题

模型的训练依赖的是对损失函数的最小化,如果在这之中某一类的数据非常的多,那么损失函数的更新将会被这个类别所干扰,导致得到的结果偏向于此类别。加入一个为分类任务正例100条,负例9900条,那么最终的预测结果全部为负例,准确度也要99%,但是这个模型并没有什么实际的作用。

解决方式

模型层面

模型层面可以通过对损失函数的改造来进行缓解。以交叉损失函数为例: \(C E=\left\{\begin{array}{rlr} -\log (p), & \text { if } & y=1 \\ -\log (1-p), & \text { if } & y=0 \end{array}\right.\)

类别加权

\(C E=\left\{\begin{array}{rlr} -\alpha \log (p), & \text { if } & y=1 \\ -(1- \alpha)\log (1-p), & \text { if } & y=0 \end{array}\right.\) 其中$\alpha$通过对训练样本中的各个类别的数量统计而来。比如有100条正样本,1w条负样本,则a的值为10000/10100

Focal loss

解决样本难以程度带来的样本不均衡问题 Focal loss

GHM loss

解决离群点对模型收敛的影响,离群点大多是标注错误所带来的误差。 GHM

数据层面

欠采样

第一种:简单的随机采样。但是存在的问题就是会丢失很多样本造成不必要的损失。 第二种:基于迭代分类的方式来采样负样本。基于全部正样本和部分负样本训练一个分类器,然后对剩下的负样本进行分类,挑选出其中的预测为正例的样本,再随机抽取一部分联合训练,依次往复,得到最终的采样训练集。

1
欠采样肯定会对样本有一定的损失,对于样本量很大且需要控制的情况下,可以考虑欠采样

过采样

通过对正样本重采样来达到设定的比例。当然也有一些方法:SMOTE 一些数据增强方式:

1
2
3
1.回译、题换、随机噪声
2.基于BERT的有条件文本生成:https://github.com/bojone/bert4keras/blob/2accce143a9b7b6164a1a3a1a38507fc03788ec9/examples/task_conditional_language_model.py
3.基于SIMBERT生成相似文本:https://github.com/bojone/bert4keras/blob/2accce143a9b7b6164a1a3a1a38507fc03788ec9/examples/basic_simple_web_serving_simbert.py

其他

阈值调整:默认情况下Sigmod函数将0.5作为阈值,可以根据样本的比例来对其进行调整 基于半监督学习或者自监督学习:利用无标签数据;丢弃标签进行数据预训练

参考

1.样本不平衡 2.半监督自监督