以下内容是个人通过查阅网上相关资料总结出的内容
具体说明数据不均衡会带来的问题:
1)在一个二分类问题中,训练集中class 1的样本数比class 2的样本数是60:1。使用逻辑回归进行分类,最后训练出的模型可能会忽略了class 2,即模型可能会将所有的训练样本都分类为class 1。
2)在分类任务的数据集中,有三个类别,分别为A,B,C。在训练集中,A类的样本占70%,B类的样本占25%,C类的样本占5%。最后我的分类器对类A的样本过拟合了,而对其它两个类别的样本欠拟合。
那么该如何解决这种样本不均衡问题?
1)过抽样
抽样是处理不平衡数据的最常用方法,基本思想就是通过改变训练数据的分布来消除或减小数据的不平衡。过抽样方法通过增加少数类样本来提高少数类的分类性能 ,最简单的办法是简单复制少数类样本,缺点是可能导致过拟合,没有给少数类增加任何新的信息。改进的过抽样方法通过在少数类中加入随机高斯噪声或产生新的合成样本等方法。
如何解决过采样中只是简单的复制少数类样本所带来的过拟合缺点?
采用过采样的典型算法SMOTE(它是通过对训练集里的小样本类别进行插值来产生额外的小样本类别数据)
2)欠抽样
欠抽样方法通过减少多数类样本来提高少数类的分类性能,最简单的方法是通过随机地去掉一些多数类样本来减小多数类的规模,缺点是会丢失多数类的一些重要信息,不能够充分利用已有的信息。
如何解决欠采样带来的无法充分利用数据问题?
可以把样本数较多的那一类分成与少类样本相同的多份,让不同的学习器使用,最后利用bagging思想。
1)采用代价敏感方法(常用,还无自己的具体实现需调用包中的)
重构训练集的方法。不改变已有算法,而是根据样本的不同错分代价给训练集中的每一个样本赋一个权值,接着按权重对原始样本集进行重构。引入代价敏感因子,设计出代价敏感的分类算法。通常对小样本赋予较高的代价,大样本赋予较小的代价,期望以此来平衡样本之间的数目差异。
2)尝试产生人工数据样本
一种简单的人工样本数据产生的方法便是,对该类下的所有样本每个属性特征的取值空间中随机选取一个组成新的样本,即属性值随机采样。你可以使用基于经验对属性值进行随机采样而构造新的人工样本,或者使用类似朴素贝叶斯方法假设各属性之间互相独立进行采样,这样便可得到更多的数据,但是无法保证属性之前的线性关系(如果本身是存在的)。
有一个系统的构造人工数据样本的方法SMOTE(Synthetic Minority Over-sampling Technique)。SMOTE是一种过采样算法,它构造新的小类样本而不是产生小类中已有的样本的副本,即该算法构造的数据是新样本,原数据集中不存在的。它基于距离度量选择小类别下两个或者更多的相似样本,然后选择其中一个样本,并随机选择一定数量的邻居样本对选择的那个样本的一个属性增加噪声,每次处理一个属性。这样就构造了更多的新生数据。
3)大样本/小样本个数=L对大样本进行L聚类
将大类中样本划分到L个聚类中,然后训练L个分类器,每个分类器使用大类中的一个簇与所有的小类样本进行训练得到。最后对这L个分类器采取少数服从多数对未知类别数据进行分类,如果是连续值(预测),那么采用平均值。
4)小样本个为N对大样本进行N聚类
设小类中有N个样本。将大类聚类成N个簇,然后使用每个簇的中心组成大类中的N个样本,加上小类中所有的样本进行训练。
5)选择合适的评价指标
常规的分类评价指标可能会失效,比如将所有的样本都分类成大类,那么准确率、精确率等都会很高。这种情况下,AUC是最好的评价指标。
注意:
对于样本不均衡问题,应该使得测试集各个类别的比例尽量和实际情况保持一致,这样在具体上线使用时能够避免实际情况和性能度量的结果相差过大。
也就是在数据处理时先进行分层采样划分出训练集合测试集再对训练集进行均衡处理等操作,分层采样(按照类别的比例进行采样)方法如下:
from sklearn.model_selection import train_test_split
x_train,x_val,y_train,y_val=train_test_split(data,label,stratify=label)
对训练集进行均衡处理是为了提高模型的性能,测试集保持和真实数据比例一致是为了更好的进行性能度量
同时在对训练集进行均衡处理时不能盲目的处理,例如进行欠采样时不应该只是简单的从大类别样本中取多少条(一方面这样会丢失一些信息,另一方面类的真实比例对于分类新的点非常重要,而这一信息在重新采样数据集时被丢失了)应该使用以上4)方法更好,数据均衡不一定非要1:1.保持在3:1之内也行
对于真实环境类别极度不均衡的情况,以上方法可能均无法很好的解决类别不均衡问题,可以通过测试集选择一个合适的阈值以此来进行类别判断,其中的问题是可能换批数据设定的阈值不再管用,需要重新设定。