数据挖掘:数据清洗——数据不平衡处理
一、什么是数据不平衡?
不平衡数据集指的是数据集各个类别的样本数目相差巨大,也叫数据倾斜。以二分类问题为例,即正类的样本数量远大于负类的样本数量。严格地讲,任何数据集上都有数据不平衡现象,一点的差异不会引起太多的影响,我们只关注那些分布差别比较悬殊的。
关于分布悬殊:如果类别不平衡比例超过4:1,那么其分类器会大大地因为数据不平衡性而无法满足分类要求的。因此在构建分类模型之前,需要对分类不均衡性问题进行处理。
不平衡数据的学习即需要在分布不均匀的数据集中学习到有用的信息。
二、不平衡数据例子
① 在二分类问题中,训练集中class 1的样本数比上class 2的样本数的比值为60:1。使用逻辑回归进行分类,最后结果是其忽略了class 2,将所有的训练样本都分类为class 1。
② 在三分类问题中,三个类别分别为A,B,C,训练集中A类的样本占70%,B类的样本占25%,C类的样本占5%。最后我的分类器对类A的样本过拟合了,而对其它两个类别的样本欠拟合。
生活中的案例:不平衡数据的场景出现在互联网应用的方方面面,如搜索引擎的点击预测(点击的网页往往占据很小的比例)、电子商务领域的商品推荐(推荐的商品被购买的比例很低)、信用卡欺诈检测(欺诈交易的应该是很少部分,即绝大部分交易是正常的,只有极少部分的交易属于欺诈交易)、网络攻击识别、癌症检测等等。
三、不平衡数据产生的问题
- 准确率虚高:不平衡的数据集上做训练和测试,其得到的准确率是虚高的。比如在不平衡数据中,正负样本的比例为9:1时,当它的精度为90%时,模型预测倾向于把样本分类为多数类。导致训练效率低下。
- 数据信息有限:少数类所包含的信息就会很有限,从而难以确定少数类数据的分布,即在其内部难以发现规律,进而造成少数类的识别率低
四、不平衡数据的处理方法
不平衡数据的处理主要可从三个方面进行考虑:
①数据角度:改变训练集样本分布 ,降低不平衡程度 。主要方法为采样,分为欠采样和过采样以及对应的一些改进方法。从数据角度出发的不平衡数据集的处理方法对应的python库是imblearn。另外可以将不平衡数据集的问题考虑为一分类(One Class Learning)或者异常检测(Novelty Detection)问题,代表的算法有One-class SVM。
②评价指标:不单单看Accuracy,从多角度对数据进行评价,如f1,AUC等。是一种可对不平衡数据考察的方面,不能解决数据不平衡问题。
③算法角度:适当地修改算法使之适应不平衡分类问题。考虑不同误分类情况代价的差异性对算法进行优化,主要是基于代价敏感学习算法(Cost-Sensitive Learning),代表的算法有adacost。
4.1 数据角度
4.1.1 扩充数据
人为获取类别中样本量过小的数据,更多的数据往往能得到更多的分布信息。
4.1.2 重采样
重采样方法是通过**增加稀有类训练样本数的上采样 (up-sampling)和减少大类样本数的下采样(down-samplings)**使不平衡的样本分布变得比较平衡,从而提高分类器对稀有类的识别率 。
4.1.2.1 上采样/过采样
上采样:从少数类的样本中进行随机采样来增加新的样本,改变训练数据的分布来消除或减小数据的不平衡。
from imblearn.over_sampling import RandomOverSampler
ros=RandomOverSampler(random_state=0) #采用随机过采样(上采样)
x_resample,y_resample=ros.fit_sample(trainset,labels)
缺点:数据集中会反复出现一些样本,可能导致过拟合,没有给少数类增加任何新的信息。
改进:
- 上采样会把小众样本复制多份,一个点会在高维空间中反复出现,这会导致一个问题,那就是运气好就能分对很多点,否则分错很多点。为了解决这一问题,可以在每次生成新数据点时,添加随机噪声经验表明这种做法非常有效。
- 较高级的上采样方法则采用一些启发式技巧 , 有选择地复制稀有类样本 , 或者生成新的稀有类样本。SMOTE算法是一种简单有效的上采样方法,该方法首先为每个稀有类样本随机选出几个邻近样本,并且在该样本与这些邻近的样本的连线上随机取点,生成无重复的新的稀有类样本。
4.1.2.2 下采样/欠采样
下采样:通过舍弃部分大类样本的方法 , 降低不平衡程度 。
缺点:丢失多数类的一些重要信息,不能够充分利用已有的信息。另外可能增大模型的偏差,因为放大或者缩小某些样本的影响相当于改变了原数据集的分布。
改进:
- 对不同的类别也要采取不同的采样比例,但一般不会是1:1,因为与现实情况相差甚远,压缩大类的数据是个不错的选择。
- 采用更好的EasyEnsemble,BalanceCascade,NearMiss算法。
from imblearn.under_sampling import RandomUnderSampler
#通过设置RandomUnderSampler中的replacement=True参数, 可以实现自助法(boostrap)抽样
#通过设置RandomUnderSampler中的rratio参数,可以设置数据采样比例
rus=RandomUnderSampler(ratio=0.4,random_state=0,replacement=True) #采用随机欠采样(下采样)
x_resample