参考:https://blog.csdn.net/weixin_36378508/article/details/114848106
参考地址:
https://www.zhihu.com/question/372186043/answer/1089033462
https://blog.csdn.net/qq_28778507/article/details/93725573
https://www.cnblogs.com/guoruibing/articles/9561035.html
这类问题我们一般称之为“长尾问题”, 如按照 class frequency 排序, 可以将 frequency 较高的 class/label 称之为 head label, frequency 较低的 class/label 称之为tail label.
1 怎样解决样本不平衡问题:
主要三个方面,数据,模型和评估方法。
数据上过采样和欠采样,使之均衡;
模型上选对样本不均衡问题不敏感的模型,如决策树;或者调整分类阈值,使得更倾向与类别少的数据
评估方法,比如ROC或者F1,focal loss等。
2 经验:
2.1 过采样up-sampling是把小众类复制多份,
欠采样 down-sampling是从大众类中剔除一些样本,或者说只从大众类中选取部分样本。
过采样会把小众样本复制多份,一个点会在高维空间中反复出现,这会导致一个问题,那就是运气好就能分对很多点,否则分错很多点。为了解决这一问题,可以在每次生成新数据点时加入轻微的随机扰动,经验表明这种做法非常有效。因为欠采样会丢失信息,如何减少信息的损失呢?
第一种方法叫做EasyEnsemble,利用模型融合的方法(Ensemble):多次欠采样(放回采样,这样产生的训练集才相互独立)产生多个不同的训练集,进而训练多个不同的分类器,通过组合多个分类器的结果得到最终的结果。
第二种方法叫做BalanceCascade,利用增量训练的思想(Boosting):先通过一次欠采样产生训练集,训练一个分类器,对于那些分类正确的大众样本不放回,然后对这个更小的大众样本欠采样产生训练集,训练第二个分类器,以此类推,最终组合所有分类器的结果得到最终结果。
第三种方法是利用KNN试图挑选那些最具代表性的大众样本,叫做NearMiss,这类方法计算量很大
2.2 将头部和尾部标签分别建模. 比如先利用 data-rich 的 head label 训练 deep model, 然后将学到的样本的 representation 迁移到 tail label model, 利用少量 tail label data 做 fine-tune.
2.3 对 label 加权, 每个 label 赋予不同的 cost. 如给予 head label 较低的 weight, 而 tail label 则给予较高的 weight, 缺点是每个 label weight 需要启发式的确定.
2.4 sparse + low rank decomposition: 这种方法可能更适应于 multi-label learning, 学术上常常假设 label matrix 可以分解为 low-rank matrix 和 sparse matrix, 这里的 low-rank matrix 对应 head label, 而 sparse matrix 对应 tail label.
2.5 每个Batch对每类样本设置比例,保证在一个Batch里是相对均衡的
2.6 focal loss(多用于检测中二分类,不是严格意义上的长尾数据) 这里介绍一下focal loss,他的目的在于通过减少易分类样本的权重,从而使得模型在训练时更专注于难分类的样本,他是在CE loss上做的修改。
但是这里有坑一定要多注意: focal loss多用于检测,在正样本和负样本比例1:1000的情况下比较有效,对于一般的样本不均衡其实效果不大,对于 easy sample dominant有作用,这两个问题并不等价。用这个loss预测出得概率都会比较低一点。若γγγ过大时,可以理解其实对小样本过于over fit,这样效果也不好,所以这是为什么在机器学习里,对于小样本尽可能使用插值法构建新样本,也不会用小样本反复训练
2.7 loss reweight 一篇新出的CVPR,目前实验表示有效:
Class-Balanced Loss Based on Effective Number of Samples
2.8 数据合成
数据合成方法是利用已有样本生成更多样本,这类方法在小数据场景下有很多成功案例
SMOTE为每个小众样本合成相同数量的新样本,这带来一些潜在的问题:一方面是增加了类之间重叠的可能性,另一方面是生成一些没有提供有益信息的样本。为了解决这个问题,出现两种方法:Borderline-SMOTE与ADASYN。
Borderline-SMOTE的解决思路是寻找那些应该为之合成新样本的小众样本。即为每个小众样本计算K近邻,只为那些K近邻中有一半以上大众样本的小众样本生成新样本。直观地讲,只为那些周围大部分是大众样本的小众样本生成新样本,因为这些样本往往是边界样本。确定了为哪些小众样本生成新样本后再利用SMOTE生成新样本。
2.9 一分类 对于正负样本极不平衡的场景,我们可以换一个完全不同的角度来看待问题:把它看做一分类(One Class Learning)或异常检测(Novelty
Detection)问题。这类方法的重点不在于捕捉类间的差别,而是为其中一类进行建模,经典的工作包括One-class SVM等。说明:对于正负样本极不均匀的问题,使用异常检测,或者一分类问题,也是一个思路。
2 如何选择
解决数据不平衡问题的方法有很多,上面只是一些最常用的方法,而最常用的方法也有这么多种,如何根据实际问题选择合适的方法呢?接下来谈谈一些我的经验。
1、在正负样本都非常之少的情况下,应该采用数据合成的方式;
2、在负样本足够多,正样本非常之少且比例及其悬殊的情况下,应该考虑一分类方法;
3、在正负样本都足够多且比例不是特别悬殊的情况下,应该考虑采样或者加权的方法。
4、采样和加权在数学上是等价的,但实际应用中效果却有差别。尤其是采样了诸如Random Forest等分类方法,训练过程会对训练集进行随机采样。在这种情况下,如果计算资源允许过采样往往要比加权好一些。
5、另外,虽然过采样和欠采样都可以使数据集变得平衡,并且在数据足够多的情况下等价,但两者也是有区别的。实际应用中,我的经验是如果计算资源足够且小众类样本足够多的情况下使用过采样,否则使用欠采样,因为过采样会增加训练集的大小进而增加训练时间,同时小的训练集非常容易产生过拟合。
6、对于欠采样,如果计算资源相对较多且有良好的并行环境,应该选择Ensemble方法。
重采样(resampling)技术:
(1). 随机欠采样 随机欠采样的目标是通过随机地消除占多数的类的样本来平衡类分布。
优点
它可以提升运行时间;并且当训练数据集很大时,可以通过减少样本数量来解决存储问题。
缺点
它会丢弃对构建规则分类器很重要的有价值的潜在信息。被随机欠采样选取的样本可能具有偏差。它不能准确代表大多数。
(2). 随机过采样(Random Over-Sampling)
过采样(Over-Sampling)通过随机复制少数类来增加其中的实例数量,从而可增加样本中少数类的代表性。 优点
与欠采样不同,这种方法不会带来信息损失。 表现优于欠采样。 缺点 由于复制少数类事件,它加大了过拟合的可能性。
(3). 信息性过采样:合成少数类过采样技术
直接复制少数类实例并将其添加到主数据集时。从少数类中把一个数据子集作为一个实例取走,接着创建相似的新合成的实例。这些合成的实例接着被添加进原来的数据集。新数据集被用作样本以训练分类模型。
优点
通过随机采样生成的合成样本而非实例的副本,可以缓解过拟合的问题。 不会损失有价值信息。
缺点
当生成合成性实例时,SMOTE
并不会把来自其他类的相邻实例考虑进来。这导致了类重叠的增加,并会引入额外的噪音。