不平衡数据下的机器学习方法简介

http://www.itongji.cn/cms/article/articledetails?articleid=3482&utm_source=tuicool&utm_medium=referral

http://www.dtted.com/portal.php?mod=view&aid=834

问题定义


那么什么是不平衡数据呢?顾名思义即我们的数据集样本类别极不均衡,以二分类问题为例,假设我们的数据集是$S$,数据集中的多数类为$S_maj$,少数类为$S_min$,通常情况下把多数类样本的比例为$100:1$,$1000:1$,甚至是$10000:1$这种情况下为不平衡数据,不平衡数据的学习即需要在如此分布不均匀的数据集中学习到有用的信息。


640.png

1).png


不平衡学习的方法


既然传统的学习算法在不平衡数据中具有较大的局限性,那么针对不平衡数据集又有怎样的解决方案呢?解决方法主要分为两个方面,第一种方案主要从数据的角度出发,主要方法为抽样,既然我们的样本是不平衡的,那么可以通过某种策略进行抽样,从而让我们的数据相对均衡一些;第二种方案从算法的角度出发,考虑不同误分类情况代价的差异性对算法进行优化,使得我们的算法在不平衡数据下也能有较好的效果。


采样  随机采样


SMOTE算法:SMOTE全称是Synthetic Minority Oversampling Technique即合成少数类过采样技术,它是基于随机过采样算法的一种改进方案,由于随机过采样采取简单复制样本的策略来增加少数类样本,这样容易产生模型过拟合的问题,即使得模型学习到的信息过于特别(Specific)而不够泛化(General),SMOTE算法的基本思想是对少数类样本进行分析并根据少数类样本人工合成新样本添加到数据集中



640 (1).png


Informed Undersampling


既然SMOTE可以解决随机过采样容易发生的模型过拟合问题,对应地也有一些采样方法可以解决随机欠采样造成的数据信息丢失问题,答案是Informed undersampling采样技术,informed undersampling采样技术主要有两种方法分别是EasyEnsemble算法和BalanceCascade算法。

640 (2).png

代价敏感学习



8大策略让你对抗机器学习数据集里的不均衡数据


1) 可以扩大数据样本吗?


你可能会认为这样做很愚蠢,但扩大样本数据总是容易被忽视。

你能收集更多的数据吗?花一秒钟,想想你是否能够收集更多和问题相关的数据。

在集合中,一个更大的数据集,就有可能挖掘出不同的或许更平衡的方面。

之后当我们寻找重复采集的数据样本时,一些小样本类数据的例子可能是有帮助的。


2) 试着改变你的绩效标准


精度是一个不适用于不平衡的数据集的绩效指标。正如我们已经看到的,这是一种误导。

在处理不平衡类时,有些更加理想的指标可以给你更加具有说服力的结果。


在我的文章中,我给更多的建议和措施去选择不同的绩效标准:“Classification Accuracy is Not Enough: More Performance Measures You Can Use”。


在这篇文章里我主要着重于讲述如何对乳腺癌患者复发这个不均衡数据集进行分类。


相比于传统的精确度,这些绩效标准可以更加深入地洞察模型的准确率:

  • 混淆矩阵:将要预测的数据分到表里来显示正确的预测(对角线),并了解其不正确的预测的类型(哪些类被分配了不正确的预测);

  • 精度:一种分类准确性的处理方法;

  • 召回率:一种分类完整性的处理方法;

  • F1分数(或F-分):精度和召回率的加权平均。



同时,我还推荐你关注一下以下几点:

  • Kappa(或者Cohen’s kappa):根据数据中集合数据的不平衡点来标准化分类精度;

  • ROC曲线:类似于精度和召回率,准确性被分为敏感性和特异性,并且可以基于这些值的平衡阈值来选择模型。



文章“Assessing and Comparing Classifier Performance with ROC Curves”中你可以学到更多关于运用ROC曲线来比较分类准确度的方法。


你是不是仍然无法确定呢?试着运用Kappa,他会告诉你一些究竟如何处理分类准确度的建议和方法。


3)尝试对你的数据重新抽样


你可以改变将要用来建立预测模型的数据集来获得更加平衡的数据集。


这种变化被称为抽样数据集,您主要可以运用以下两种方法来使数据分类更加均衡:

1.您可以从代表性不足的类(又称为过抽样或者更加正式的抽样来代替)添加实例的副本,或者

2.您可以从过度代表类里删除实例,称为抽样不足。

这些方法往往很容易实现,而且运行速度也很快。因此我认为他们都是不错的出发点。


你可以通过维基百科题为“Oversampling and undersampling in data analysis”的文章了解更多相关咨询。


一些经验的规则


当你的数据量很大时可以考虑测试抽样不足(一万或者十万条记录或更多)

当你没有大量的数据时可以考虑测试抽样过度(一万条记录或更少)

考虑测试随机和非随机的抽样方案(如分层)。

考虑用不同的重抽样率进行测试(例如,在一个二元分类问题中,您不必一定要针对1:1的比例,可以尝试其他比例)


4) 尝试生成人工样本


一种简单生成人工样本的方法是从在少数类的实例中随机抽样属性。


在数据集中,你可以根据经验对它抽样或者你可以使用类似于朴素贝叶斯这种可以在反向运行时,对每个属性进行独立抽样的模型。你将有更多的不同的数据,但可能不会保留其属性之间的非线性关系。


这里有一些系统方法可以用来生成人工演变。其中最流行的算法被称为SMOTE或Synthetic Minority Over-sampling技术。


正如其名,SMOTE是过度抽样的方法。它的工作原理是从小类的数据中生成人工样本,而不是创建副本。该算法选择两个或更多个类似的例子(使用距离度量),然后随机干扰一个实例中的一个属性,比较其差异。


想要了解更多关于SMOTE方法,请搜索2002年名为“SMOTE: Synthetic Minority Over-sampling Technique”的原文章。


现在有很多的SMOTE算法的实现方法,例如:

在Python,一起来看看在“UnbalancedDataset”模块。它提供了许多SMOTE实现方法,以及各种其他再抽样技术,你都可以尝试;

在R中,DMwR 包提供SMOTE的实现方法;

在Weka中,你可以使用SMOTE supervised filter


5) Try Different Algorithms


通常来说,我会强烈建议你对于所有问题不要总是使用自己最喜欢的模型。对于所给的问题你至少应该用不同类型的算法对其进行抽查。


欲了解更多关于抽查的方法,请参阅我的文章“Why you should be Spot-Checking Algorithms on your Machine Learning Problems”。


话虽这么说,决策树往往在处理不平衡类数据集表现不错。在创建树的过程中使用类变量的分裂规则,可以强制地将两个类很好的进行处理。


如果有疑问,请尝试一些流行的决策树算法,如C4.5,C5.0,CART和随机森林。


对于使用决策树的一些R代码,请参阅我的文章,标题为“Non-Linear Classification in R with Decision Trees”。


例如,对于Python和scikit-learn中使用CART的一个例子,请参考我的文篇,名为“Get Your Hands Dirty With Scikit-Learn Now”的文章。


6) 尝试名义变量模型


您可以使用相同的算法,但是在不同问题中他们可能会给出不同的观点。


因为在训练过程中,对于小类数据会产生分类错误,因此名义变量分类会产生额外费用。这些名义变量会使模型偏向于更加注重少数类数据。


通常来说掌握一类名义变量或者权重是为了学习方法。例如一些方法的名义变量penalized-SVM和penalized-LDA。


另外,对于名义变量模型也具有通用框架。例如,Weka中有一个CostSensitiveClassifier,它可以封装任何分类和自定义分类应用中错过的名义变量矩阵。


如果你锁定到一个特定的算法并且无法重新取样或是你得到的结果不好时,使用名义变量是可取的。它提供了另一种方法来“平衡”类。建立名义变量矩阵是很复杂的,也许您将不得不尝试各种设置名义变量的方法,看看什么方法是最适合用来解决你的问题。


7) 尝试从不同的观点进行思考


对于研究不平衡数据集的邻域。他们有自己的算法,措施和术语。


从这些观点处罚,纵观和思考你的问题,有时一些想法会有所改变。


两个你可能想要考虑的是异常检测和变化检测。


异常检测是罕见事件的检测。这可能是根据一系列的系统调用,通过它的振动或一个由程序指示的恶意活动而产生的机器故障。这样的事件相比正常操作是罕见的。


这种思维的转变在于考虑以小类作为异常值类,它可以帮助你获得一种新方法来分离和分类的样本。


除了变化检测是找寻找它的变化而不是差异以外,变化检测类似于异常检测。这可能是在观察使用模式或银行交易过程中用户的行为变化。


对于分类的问题,这两个转变具有更加实时的角度,它可能会给你一些新的方式去思考你的问题以及让你尝试更多新的技术。


8) 尝试一些新的创意


在你的问题里面挖掘并思考如何把它分解成更小的问题,这些问题更容易处理。


为了寻找灵感,看一看别人对于问题:“In classification, how do you handle an unbalanced training set?”给出的一些有创意的答案。


例如:

分解你的大类变成小类…

…使用一类分类…(比如像将其作为异常检测对待)

…不是将不平衡类训练集重抽样成一组平衡集,而是一些平衡集。在这个集合中,同时运行所有集产生的结果可能比只运行一个集的结果更好。


这些只是一小部分你可以尝试的有趣的和创造性的想法。



分析样本大小对非平衡数据分类的影响


1 影响稀有类分类的因素


通常认为影响稀有类分类的因素是不平衡的类分布(Imbalanced class distribution),还有一些重要的因素影响稀有类分布,如小样本规格(Small sample size)和分离性(Separability)[2]。下面简单讨论这些因素对稀有类分类的影响。


  (1)不平衡的类分布:研究表明,类分布越是相对平衡的数据分类的性能越好。参考文献[4]探讨了训练集的类分布和判定树分类性能的关系,但是不能确定多大的类分布比率使得分类性能下降。研究表明,在有些应用中1:35时不能很好地建立分类器,而有的应用中1:10时就很难建立了。


  (2)样本大小:给定特定的类分布比率(稀有类实例和普通类实例的比值),样本大小在确定一个好的分类模型中起着非常重要的作用,要在有限的样本中发现稀有类内在的规律是不可能的。改变该数据集的样本大小,使得稀有类实例为50个,非稀有类实例为1 000个。结果是类分布同样为1:20,但是前者没有后者提供的稀有类信息量大,稀有类分类的性能没有后者高。


  (3)分离性:从普通类中区分出稀有类是稀有类分类的关键问题。假定每个类中存在高度可区分模式,则不需要很复杂的规则区分它们。但是如果在一些特征空间上不同类的模式有重叠就会极大降低被正确识别的稀有类实例数目。


根据以上分析可知,由于影响稀有类分类的因素多种多样,使得稀有类分类问题更加复杂,分类的性能降低。本文在其他因素相同的前提下研究样本大小对稀有类分类的影响。实验证明在类分布相同的情况下,样本越大稀有类分类的性能越好。


2 稀有类分类的评估标准


常用的分类算法的评估标准有:预测的准确率、速度、强壮性、可规模性及可解释性。通常使用分类器的总准确率来评价普通类的分类效果。而对于稀有类分类问题,由于关注的焦点不同,仅用准确率是不合适的。


在稀有类分类问题中应更关注稀少目标类的正确分类率。在评价稀有类分类时,还应该采用其他的评价标准。


这里假设只考虑包含两个类的二元分类问题,设C类为目标类,即稀有类,NC为非目标类。根据分类器的预测类标号和实际类标号的分布情况存在如表1所示的混合矩阵(Confusion Matrix)。


  根据表1得到如下度量:



  3 组合分类器介绍

组合分类器是目前机器学习和模式识别方面研究的热门领域之一,大量研究表明,在理论和实验中,组合方法比单个分类模型有明显的优势。常用的组合分类器有:Bagging、Random Forest及Rotation Forest。


  3.1 Bagging介绍

Bagging[5]算法是一种投票方法,各个分类器的训练集由原始训练集利用可重复取样(bootstrap sampling)技术获得,其过程如下:对于迭代t(t=1,2,…,T),训练集St采用放回选样,由原始样本集S选取。由于使用放回选样,S的某些样本可能不在St中,而其他的可能出现多次。由每个训练集St学习,得到一个分类算法Ct。为对一个未知的样本X分类,每个分类算法Ct返回它的类预测,算作一票。Bagging的分类算法C*统计得票,并将得票最高的类赋予X[1]。


  3.2 Random Forest介绍

随机森林是一个包含多个决策树的分类器, 并且其输出的类别是由个别树输出的类别的众数而定。 Leo Breiman和Adele Cutler发展出推论出随机森林的算法。 而 "Random Forests" 是他们的商标。 这个术语是1995年由贝尔实验室的Tin Kam Ho所提出的随机决策森林(random decision forests)而来的。这个方法则是结合 Breimans 的 "Bootstrap aggregating" 想法和 Ho 的"random subspace method"" 以建造决策树的集合。重复M次这样的抽样过程分别得到M棵决策树的学习样本。单棵决策树建造过程不进行剪枝,森林形成之后,对于一个新的样本,每棵树都得出相应的分类结论,最后由所有树通过简单多数投票决定分类结果。


  3.3 Rotation Forest介绍

Rotation Forest是一个基于判定树的组合分类器,其基本思想如下:假设x=[x1,…,xn]为不含类标号的数据集X的一个元组,则该数据集可以表示为N×n的矩阵;定义Y=[y1,…,yN]为X中元组对应的类标号集合,其中yi∈{w1,…,wc};定义D1,…,DL为组合方法中的基分类器;F为属性集合。Rotation Forest意在建立L个不同的准确的分类器。基于新的数据集训练得到Di分类器。L次不同的属性集划分得到L个不同的提取特征集,映射原始数据得到L个不同的数据集,分别训练得到L个分类器。对于未知样本的实例X,组合L个分类器计算每个类的置信度,将其归类于置信度最高的类中[6,7]。


4 实验结果及其分析


为了验证稀有类分类算法受到样本规格大小的影响,使用UCI机器学习库[8]中的稀有类数据集sick作为实验数据集。实验采用十折交叉验证的方法统计分类的准确率。


sick数据集的基本情况为:30个属性(带类标号)、2个类(0,1),共有实例3 772条。其中sick和negative类分别拥有实例数目3 541和231,分别占总样本比例93.88%和6.12%。sick类可看作稀有类。


  4.1 实验结果

基于每个数据集,采用weka平台提供的unsupervised resample数据预处理方法改变样本规格的大小,使得实例数目分别是原始数据的倍到10倍不等。对这些处理后的数据集分别应用组合分类器bagging、FandomForest和Rotation Forest算法进行分类。

表2是应用Rotation Forest算法在处理后得到的sick数据集上关于sick类的实验结果。sick数据集样本被扩充了若干倍不等。


表3是应用Random Forest算法在处理后得到的sick数据集上关于sick类的实验结果。sick数据集样本被扩充了若干倍不等。


表4是应用Bagging算法在处理后得到的sick数据集上关于sick类的实验结果。Bagging算法在sick数据集上实验时,样本被扩充到10倍后,recall值仍没有达到1,后来实验又将样本扩充至12倍,但由于内存不够实验终止。


通过上述表格中的实验结果,可以看到随着样本规格变大,衡量稀有类分类的这些参数也呈递增。这也意味着随着稀有类实例数目的增加,算法可以获得更多关于稀有类的信息,从而有利于对稀有类实例的识别。



令人讨厌的非平衡数据


如果你的数据存在这种不平衡,分析得出的结论也一定是有偏的,往往分类结果会偏向于较多观测的类。对于这种问题该如何处理呢?起先我的想法很简单,构造1:1的数据,要么将多的那一类砍掉一部分,要么将少的那一类进行Bootstrap简单复制。但这样做是存在问题的,对于第一种方式,砍掉的数据会导致某些隐含信息的丢失;对于第二种方式,简单复制,又会使模型产生过拟合问题。那该怎么办?


在网络中寻找求解办法,发现2002年Chawla就提出了SMOTE算法(合成少数过采样技术),而且该方法目前是处理非平衡数据的常用手段,受到学术界的一致认同。下面就讲讲该算法的思想:


1)采样最邻近算法,计算出每个少数类样本的K个近邻


2)从K个近邻中随机挑选N个样本进行随机线性插值


3)构造新的少数类样本

构造公式:


4)将新样本与原数据合成,产生新的训练集


为了说明SMOTE算法的思路,我们举个简单例子:

如果有一个少数类的样本点为(2,3,10,7),从K个近邻中随机挑选2个点分别为(1,1,5,8)和(2,1,7,6),参数的随机数为0.3,那么构造的2个新样本点为:


上面我们介绍了关于SMOTE算法实现数据平衡的理论思想,在R语言中该如何实现这样的理论呢?DMwR包中的SMOTE()函数就可以实现这样的功能,具体函数的语法和参数含义如下:


SMOTE(form, data, perc.over = 200, k = 5, perc.under = 200,

      learner = NULL, ...)

form:为一个公式形式,类似于y~x1+x2+x3

data:为不平衡的数据框

perc.over:定义过采样的抽样次数,即对于少数类样本点,需要为每个点重新构造多少个点。默认值为200,即重新为每个少数类样本点构造200/100=2个点。

k:指定K邻近算法中的参数K值,即选取K个最邻近的点,默认值为5

perc.under:定义欠采样的抽样次数,即从多数类样本中选择perc.under倍于新生成的样本数量,默认为200,即从多数类样本中选择200/100=2倍于新生成样本的数量


下面就使用实例数据来验证一下非平衡数据处理前后的模型结果,数据来源于C50包中的客户流失数据:

```{r}

library(C50)

data(churn)

train = churnTrain

test = churnTest


#查看一下训练集和测试集数据的平衡状态

table(train$churn)

prop.table(table(train$churn))


table(test$churn)

prop.table(table(test$churn))




未来世界是复杂的不确定的,而现在的教育是传统的和功利的;提供一个窗口理解现代世界的含义。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值