样本不均衡处理方式

一、数据不平衡现象

在学术研究与教学中,很多算法都基于一个假设,那就是数据分布是均匀的。但在实际数据中,数据往往分布得很不均匀,都会存在“长尾现象”,也就是“二八原理”。不平衡程度(即正负样本比例类似)的两个问题,解决的难易程度也可能不同,因为问题难易程度还取决于我们所拥有数据有多大。可以把问题根据难度从小到大排个序:大数据+分布均衡<大数据+分布不均衡<小数据+数据均衡<小数据+数据不均衡。说明:对于小数据集,机器学习的方法是比较棘手的。对于需要解决的问题,拿到数据后,首先统计可用训练数据有多大,然后再观察数据分布情况。经验表明,训练数据中每个类别有5000个以上样本,其实也要相对于特征而言,来判断样本数据是不是足够,数据量是足够的,正负样本差一个数量级以内是可以接受的。不太需要考虑数据不平衡问题

二、处理方法

1、采样

关于采样问题的另外一种说法:
采样分为上采样(Oversampling)和下采样(Undersampling),上采样是把小众类复制多份,下采样是从大众类中剔除一些样本,或者说只从大众类中抽取部分样本。
随机采样最大的优点是简单,但缺点也很明显。上采样后的数据集中会反复出现一些样本,训练出来的模型有一定的过拟合;而下采样的缺点显而易见, 那就是最终的训练集丢失了数据,模型只学到了总体模式的一部分。
上采样会把小众样本复制多份,一个点会在高维空间中反复出现,这会导致一个问题,那就是运气好就能分队很多点,否则分错很多点。为了解决这一问题,可以在多次生成新数据点时加入轻微的随机扰动,经验表明这种做法非常有效。

1)过采样:增加一些少数类样本使得正、反例数目接近,然后再进行学习。即是过采样

(1)随机过采样
随机过抽样是增加少数类样本数量,可以事先设置多数类与少数类最终的数量比例,在保留多数类样本不变的情况下,根据比例随机复制少数类样本,在使用的过程中为了保证所有的少数类样本信息都会被包含,可以先完全复制一份全量的少数类样本,再随机复制少数样本使得满足数量比例,具体步骤如下:

  • 首先在少数类Smin集合中随机选中一些少数类样本
  • 然后通过复制所选样本生成样本集合E
  • 将它们添加到Smin中来扩大原始数据集从而得到新的少数类集合Smin−new
    ​Smin重的总样本数增加了|E|个新样本,且Smin-new的类分布均衡度进行了相应的调整,如此操作可以改变分布平衡度从而达到所需水平

缺点
对于随机过采样,由于需要对少数样本进行复制来扩大数据集,造成模型训练复杂度加大。另一方面也容易造成模型的过拟合问题,因为随机过采样是简单的对初始样本进行复制采样,这就使得学习器学得的规则过于具体化,不利于学习器的泛化性能,造成过拟合问题。
为了解决随机过采样中造成模型过拟合问题,又能保证实现数据集均衡的目的,出现了过采样法代表性的算法SMOTE和Borderline-SMOTE算法

(2)SMOTE算法
SMOTE全称是Synthetic Minority Oversampling即合成少数类过采样技术
主要思想是:利用特征空间中少数样本之间的相似性来建立人工数据,特别是,对于子集Smin<S,对于每一个样本Xi<Smin使用K-近邻法,其中K-近邻被定义为考虑Smin中的K个元素本身与Xi的欧式距离在n维特征空间X中表现为最小幅度值的样本。由于不是简单地复制少数类样本,因此可以在一定程度上避免分类器的过度拟合,实践证明此方法可以提高分类器的性能。
流程如下:
在这里插入图片描述
缺点:
1)由于对每个少数类样本都生成新样本,因此容易发生生成样本重叠的问题。
2)在SMOTE算法中,出现了过度泛化的问题,主要归结于产生合成样本的方法。特别是,SMOTE算法对于每个原少数类样本产生相同数量的合成数据样本,而没有考虑其邻近样本的分布特点,这就使得类间发生重复的可能性增大。
解释缺点2)的原因:结合前面所述的SMOTE算法的原理,SMOTE算法产生新的人工少数类样本过程中,只是简单的在同类近邻之间插值,并没有考虑少数类样本周围多数类样本的分布情况。如下图所示,绿色正号1、2分布在多数类样本周围,它们离多数类样本最近,这就导致它们有可能被划分成多数类样本。因此,SMOTE算法的样本生成机制存在一定的盲目性。

(3)Broderline-SMOTE算法
原始的SMOTE算法对所有的少数类样本都是一视同仁的,但实际建模过程中发现那些处于边界位置的样本更容易被错分,因此利用边界位置的样本信息产生新样本可以给模型带来更大的提升。Borderline-SMOTE便是将原始SMOTE算法和边界信息算法结合的算法。
算法流程如下:
在这里插入图片描述
上面式子表明,只有最近邻样本集中多数类多于少数类的那些Xi才会被选中形成“危险集”(DANGER)。因此,DANGER集中的样本代表少数类样本的边界(最容易被错分的样本)。然后对DANGER集中使用SMOTE算法在边界附近产生人工合成少数类样本。

2)欠采样
直接对训练集中多数类样本进行"欠采样"(undersampling),即去除一些多数类中的样本使得正例、反例数目接近,然后再进行学习。即是欠采样。

(1)随机欠采样
随机欠采样顾名思义即从多数类Smaj中随机选择一些样样本组成样本集 E。然后将样本集 E从Smaj中移除。新的数据Snew-maj=Smaj-E。
缺点:
随机欠采样方法通过改变多数类样本比例以达到修改样本分布的目的,从而使样本分布较为均衡,但是这也存在一些问题。对于随机欠采样,由于采样的样本集合要少于原来的样本集合,因此会造成一些信息缺失,即将多数类样本删除有可能会导致分类器丢失有关多数类的重要信息。
Informed欠抽样算法可以解决传统随机欠采样造成的数据信息丢失问题,且表现出较好的不均衡数据分类性能。其中有一些集成(ensemble)的想法,主要有两种方法,分别是EasyEnsemble算法和BalanceCascade算法。

(2)EasyEnsemble算法
它把数据划分为两部分,分别是多数类样本和少数类样本。算法流程如下:
1)从多数类中有放回的随机采样n次,每次选取与少数类树木相近的样本个数,那么可以得到n个样本集合记作{S1maj,S2maj,…Snmaj}
2)然后,将每一个多数类样本的子集与少数类样本合并并训练出一个模型,可以得到n个模型
3)最终将这些模型组合形成一个集成学习系统,最终的模型结果是这n个模型的投票值。
可以看到,EasyEnsemble的想法是多次随机欠抽样,尽可能全面地涵盖所有信息,算法特点是利用boosting减小偏差(Adaboost)、bagging减小方差。实际应用的时候可以尝试选用不同的分类器来提高分类的效果。

(3)BalanceCascade算法
BalanceCascade算法基于Adaboost,将Adaboost作为基分类器,其核心思路是:
1)在每一轮训练时都使用多数类与少数类数量相等的训练集,训练出一个Adaboost基分类器。
2)然后使用该分类器对全体多数类进行预测,通过控制分类阈值来控制假正例率(False Positive Rate),将所有判断正确的类删除。
3)最后,进入下一轮迭代中,继续降低多数类数量。
在这里插入图片描述
3)综合采样
目前为止我们使用的重采样方法几乎都是只针对某一类样本:对多数类样本欠采样,对少数类样本过采样。也有人提出将欠采样和过采样综合的方法,解决样本类别分布不平衡和过拟合问题,本部分介绍其中的SMOTE+Tomek Links和SMOTE+ENN。
(1)SMOTE+Tomek Links
Tomek Links
Tomek links被定义为相反类最近邻样本之间的一对连接。
在这里插入图片描述
使用这种方法,如果两个样本来自Tomek Links,那么他们中的一个样本要么是噪声要么它们都在两类的边界上。所以Tomek Links一般有两种用途:在欠采样中:将Tomek Links中属于是多数类的样本剔除;在数据清洗中,将Tomek Links中的两个样本都剔除。
SMOTE+Tomek Links
SMOTE+Tomek Links方法的算法流程非常简单:
1、利用SMOTE方法生成新的少数类样本,得到扩充后的数据集T
2、剔除T中的Tomek Links对
普通的SMOTE方法生成的少数类样本是通过线性插值得到的,在平衡类别分布的同时也扩张了少数类的样本空间,产生的问题是可能原本属于多数类样本的空间被少数类“入侵”,容易造成模型的过拟合。
Tomek Links对寻找的是那种噪声点或者边界点,可以很好地解决“入侵”的问题,下图红色加号为SMOTE产生的少数类样本,可以看到,红色样本“入侵”到原本属于多数类样本的空间,这种噪声数据问题可以通过Tomek Links很好地解决。

(2)SMOTE+ENN
SMOTE+ENN方法和SMOTE+Tomek Links方法的想法和过程都是很类似的:
利用SMOTE方法生成新的少数类样本,得到扩充后的数据集T
对T中的每一个样本使用KNN(一般K取3)方法预测,若预测结果与实际类别标签不符,则剔除该样本。

加粗样式3)经验法则
考虑样本(超过1万,十万甚至更多)进行欠采样,即删除部分样本;
考虑样本(不足为1甚至更少)进行过采样,即添加部分样本的副本
考虑尝试随机采样与非随机采样两种采样方法
考虑对各类别尝试不同的采样比例,不一定是1:1
考虑同时使用过采样与欠采样

2、加权

3、合成数据

4、更换算法

1)LightGBM
(1)二分类处理
在LGBM的文档中,可以看到有两个参数来处理类别不平衡,分别是is_unbalance和scale_pos_weight 。
在这里插入图片描述
在上图中的介绍中,这2个参数只能选其一,不能同时选。这说明了什么呢?这2个参数肯定是起到了相同的作用。这2个参数的关系是什么呢?在issue中找到了答案:
if is_unbalance = true, weight of each positive sample / weight of each negative sample = (num_negative_sample / num_positive_sample) * scale_pos_weight_
如果我们设置is_unbalance为True的话,那么scale_pos_weight就是默认值1,那么:每一个正样本的权重/每一个负样本的权重就等于负样本的样本数/正样本的样本数。
如果我们设置scale_pos_weight的话,那么应该设置成number of negative samples / number of positive samples,因为在上图中已经写明了:scale_pos_weight代表的是正类的权重。这样也就和is_unbalance参数的意思对应上了。(注:很多人对于设置scale_pos_weight是懵逼的,我自己已经明确给出了答案,包括xgb也是一样的。)
2个参数如何解决类别不平衡的问题呢?
很明显,可以看到,通过设置这两个参数,可以得到正样本和负样本的权重,样本的权重是什么意思呢?我们知道,在LGBM进行分裂的过程中,我们求出了样本的一阶导数和二阶导数,在此基础上,就会乘以样本的权重。
这里有一个issue涉及到了is_unbalance背后用的算法,方便读者进行更深入的了解。

(2)多分类处理
LGBM对多分类的不平衡问题也进行了完美地处理。它设计了参数class weight。在文档中介绍如下:
在这里插入图片描述
一共提到了以下几点:
1、要不传入是dict,格式是class_weight={1: 1, 0: 2}这样;要不传入"balanced";要不传入是None。
2、如果传入的是dict,那么每个类的权重正如你传入的那样。
3、如果传入的是"balanced",那么会自动根据标签的值来算出每个类的权重,每个类的权重是与每个类别样本出现的次数成反比的。具体是根据公式: n_samples / (n_classes * np.bincount(y))。np.bincount(y)是numpy的一个很有趣的函数,不了解的可以参考该篇文档。我们更形象地说明,我在这里举一个例子,假如我们有10个样本,标签分别为[0,2,2,1,1,1,1,1,1,1],这典型是不平衡的。那么np.bincount(y)输出的值为[1,7,2],n_samples/(n_classesnp.bincount(y))输出的值分别为10/31,10/37,10/32。这显然类别权重是与类别的样本个数成反比的。(注:这里有一个背景,就是lgbm中多类别必须设置为0,1,2,3…这样的形式)
4、如果传入的是None,那么每个类别的权重是一样的。
5、当然,与二分类一样,如果我们也传入了sample_weight,那么每个类的权重还要再乘以sample_weight。(注:sample_weight是LGBM是很少用到的一个功能,它一般是通过fit方法传入的,关于它的使用需要详细参考官方文档)

2)Xgboost
XGB相比于LGBM,只有一个涉及到不平衡类的参数scale_pos_weight。在官方文档上是这么介绍的:
在这里插入图片描述
可以看到,定义与LGBM是相同的,即:如果我们设置scale_pos_weight的话,那么应该设置成number of negative samples / number of positive samples。
在xgboost中特意提到了处理不平衡数据集:
官网的意思大致可理解如下:
1、scale_pos_weight 是用来调节正负样本不均衡问题的,用助于样本不平衡时训练的收敛。
2、如何仅仅关注预测问题的排序或者AUC指标,那么尽管可以调节此参数。
3、如果希望得到真正的预测概率则不能够通过此参数来平衡样本。什么意思呢,让我们来举个例子:假如我们现在需要通过体重来预测男女,有三个人体重分别为50kg、60kg、70kg。假设他们是男生的真正概率是:0.4、0.6、0.8。那么好,我现在模型预测出的概率为:0.7、0.8、0.9。如果讲预测概率的话,显然模型效果很差,但是我们预测的男生概率的排序以及 ROU 曲线(包括对应 AUC 值)都不会改变。如果我们想真正预测概率,而是利用一些参数,如将max_delta_step设置到一个有限的数(比如:1)可以获得效果提升.
(注意:LGBM的scale_pos_weight与XGB的scale_pos_weight的意义是一样的,也就是说,如果我们在LGB中使用了scale_pos_weight,那么得不到的概率也不再是真正的预测概率了)!
在第3点中,如果我们想真正预测概率,当然还有其它一些参数可以调整,比如:

  • min_child_weight
    默认为1。是每个叶子里h的和至少是多少。对正负样本不均衡时的0-1分类而言,假设h在0.01附近,min_child_weight为1意味着叶子节点中最少需要包含100个样本。这个参数非常影响结果,控制叶子节点中二阶导的和的最小值,该参数值越小,越容易 overfitting。
  • eta
    shrinkage参数,用于更新叶子节点权重时,乘以该系数,避免步长过大。参数值越大,越可能无法收敛。把学习率eta设置的小一些,小学习率可以使得后面的学习更加仔细。
  • max_delta_step
    每个叶子允许输出的最大增量步长。 如果该值设置为0,则表示没有约束。 如果将其设置为正值,则可以帮助使更新步骤更加保守。 通常不需要此参数,但当类非常不平衡时,它可能有助于逻辑回归。 将其设置为值1-10可能有助于控制更新。
    源码如何利用Scala_pos_weight来平衡样本呢?
    if(info.labels[i]==1.0f) w*=param_.scale_pos_weight
    可以看出,增大了少数样本的权重

5、使用其他的评价指标

error rate 不能用于非均衡的数据集,因此可以使用其他的评价指标;
Precision 计算TP/TP+FP,实际被检索到的(TP+FP)
recall TP/(TP+FN),应该被所索引到的(TP+FN)
F1 score precision和recall的调和平均

三、合适处理方法的选择标准

1、在正负样本都非常之少的情况下,应该采用数据合成的方式;
2、在负样本足够多,正样本非常之少且比例及其悬殊的情况下,应该考虑一分类方法;
3、在正负样本都足够多且比例不是特别悬殊的情况下,应该考虑采样或者加权的方法;
4、采样和加权在数学上是等价的,但实际应用中效果却有差别。尤其是采样了诸如Random Forest等分类方法,训练过程会对训练集进行随机采样。在这种情况下,如果计算资源允许上采样往往要比加权好一些;
5、另外,虽然上采样和下采样都可以使数据集变得平衡,并且在数据足够多的情况下等价,但两者也是有区别的。实际应用中,我的经验是如果计算资源足够且小众类样本足够多的情况下使用上采样,否则使用下采样,因为上采样会增加训练集的大小进而增加训练时间,同时小的训练集非常容易产生过拟合;
6、对于下采样,如果计算资源相对较多且有良好的并行环境,应该选择Ensemble方法。

参考文章
引文一
引文二

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值