本文转自:http://www.36dsj.com/archives/35137
http://blog.csdn.net/heyongluoyao8/article/details/49408131
英文版本:http://machinelearningmastery.com/tactics-to-combat-imbalanced-classes-in-your-machine-learning-dataset/
你是不是也经历过这样的事?
当你正在处理你的数据集的时候,你建立了一个分类模型并且它的精确度达到了90%,这时,你一定会想:这个结果太棒了!但是当你继续更深地挖掘数据时你会发现这个90%的精确度只是一类数据的精确度,见鬼了!
以上是一个不均衡数据集的例子,这样的不均衡数据集有时会引起这样糟糕的结果。在这篇文章中你将可以领略一系列对抗上述例子的方法,在机器学习过程中,这些方法可以帮助你在挖掘或者训练不均衡数据集时获得一个比较好的结果。
在你的机器学习中发现一些平衡点
我们开始着手处理不均衡数据
我总是收到关于不均衡数据问题的邮件,例如:
“在我的训练样本里有一个二项分类问题,其中有一个数据集是比例为60:1的数据集,于是我对它运用了逻辑回归的训练方法,但是得到的结果是忽略这一个比率为60:1的数据集的训练结果。
再例如:
“现在我正在运行一个分类模型。在我的数据集里面一共有3类数据,这里我们称它们分别为A,B和C,但是在我的训练数据集里面A,B和C三类数据分别占了70%,25%和5%。在大多数情况下,结果都过度拟合A类数据。你能给我一些建议来解决这个问题吗?
我尝试写了很多方法并且试图找出最好的方式去解决这个问题。最终我采用了我一个学生的建议:
也许你即将推出的某一篇博客文章可以解决在训练模型中表现出高度不平衡的数据的问题,并且概述其方法和期望。
挫败感!
在运行模型时,不均衡数据会引起很多偏差和误导。
当你发现你的研究里包含了不平衡类并且导致你所谓的好的结果成为了泡沫,你会感到非常沮丧。
当你在书籍,文章和博客里找不到你想要的可以解决不均衡数据的建议或方法时,打击会再一次降临。
放轻松点吧,这里有很多点子和方法可以解决这类不均衡数据的问题,你可以针对不均衡数据建立一个预测模型。
什么是不均衡数据?
不均衡数据通常是发生在分类数据不均衡的分类问题中。
打个比方说,现在有一个包含了100行数据的二项分类问题(两类数据)。其中有80行数据代表的是数据类型一,其余20行代表的是数据类型二。
这就是一个不均衡数据(不平衡类数据),它的一类数据和二类数据比是80:20或者说4:1.
你的不平衡类问题可能发生在二项分类问题或者多项分类问题中。大多数方法都可以运用在这两种问题上。
因此,接下来的我们主要是针对二项分类问题进行分析讨论,因为这样比较容易去理解和描述。
不平衡现象是一种常见现象
大多数分类数据集是不会拥有完全相等的分类数据集,但小的差异往往是没有影响的。
在这些问题中有些不平衡问题不仅仅是常见,而是人们可以预想到的。例如,在欺诈交易数据集分类问题中数据集是不平衡。该交易的绝大部分是属于“不是诈骗”类,只有极少数会在“欺诈”级。
另一个例子是客户流失的数据集,其中客户绝大多数保持服务(“无流失”级)只有一小部分的顾客取消其认购(“流失”级)。
在上诉的例子中,如果有一种分类不平衡率达到4:1那么这个不平衡可能会导致结果出现误差。
精度悖论
在这篇文章的介绍当中,精度悖论是一些特定情况的名称。
这个准确性指标的例子告诉我们,有优异的精度(如90%)但是这个准确性只是反映基本的类分布。
这是很常见的,因为在评估分类问题的模型时,分类精度通常是我们第一个采用的措施方法。
偏向一类数据!
当我们训练的不均衡数据时,我们的模型怎么了?
正如你设想的一样,在数据不均衡的情况下,我们得到90%的准确率(比如包含90%的数据类型一的实例)是因为我们的模型观察数据并且智能地总是根据数据类型一的数据进行预测,并且尽量达到最高精度。
当我们规则基于这个方法进行的时候似乎得到的是最好的答案。但是如果你在最后的模型中仔细考察这个规则,你会发现似乎这个方法是忽略其他数据在对一类数据进行预测。
八大战术,对抗不平衡类数据
现在,我们已经了解了什么是不均衡数据以及为什么他会引起分类精度的误差。
所以我们的应对解决方法是什么呢?
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?”给出的一些有创意的答案。
例如:
分解你的大类变成小类…
…使用一类分类…(比如像将其作为异常检测对待)
…不是将不平衡类训练集重抽样成一组平衡集,而是一些平衡集。在这个集合中,同时运行所有集产生的结果可能比只运行一个集的结果更好。
这些只是一小部分你可以尝试的有趣的和创造性的想法。
对于更多的想法,请搜索reddit 文章——“Classification when 80% of my training set is of one class”的评论。
选择一种方法,然后实际操作它
你没有必要去做一个精通所有方法的奇才或者统计学家建立一个精确并且可靠的不平衡类数据集模型。
以上我们已经讲述了许多可以用在不平衡类数据集模型的技术和方法。
但愿这里有一到两个方法的模型你可以快速地较好地理解并且运用,例如:改变你精确度的指标和重新对你的数据集进行抽样。这两个方法都是比较快速的并且对问题影响会很明显。
那么你想要尝试哪一个方法呢?
总结
记住,我们不可能知道哪一个方法会得出最好的结果。
你可以发散地选择这个方法或者那个方法,但是,在最后我给你的最好的建议是“变成科学家”并且根据经验测试每一个方法,选择结果做好的那一个。
从点点滴滴开始做起,根据自己现有的知识一步一步完善。
还有什么呢?
这里有一些可以参考的相关资料给您提供参考,当然前提是你知道去哪里获取他们。
以下是一些我已经度过并且我认为比较有价值的资料。如果你想要更近一步对这个问题进行研究和探索,你可以点击以下链接。
相关书籍
- Imbalanced Learning: Foundations, Algorithms, and Applications
相关报刊文章
- Data Mining for Imbalanced Datasets: An Overview
- Learning from Imbalanced Data
- Addressing the Curse of Imbalanced Training Sets: One-Sided Selection(PDF)
- A Study of the Behavior of Several Methods for Balancing Machine Learning Training Data
原文标题:8 Tactics to Combat Imbalanced Classes in Your Machine Learning Dataset