处理不均衡数据

一、什么是数据不平衡

在学术研究与教学中,很多算法都有一个基本假设,那就是数据分布是均匀的。当我们把这些算法直接应用于实际数据时,大多数情况下都无法取得理想的结果。因为实际数据往往分布得很不均匀,都会存在“长尾现象”,也就是所谓的“二八原理”。下图是新浪微博交互分布情况:

可以看到大部分微博的总互动数(被转发、评论与点赞数量)在0-5之间,交互数多的微博(多于100)非常之少。如果我们去预测一条微博交互数所在档位,预测器只需要把所有微博预测为第一档(0-5)就能获得非常高的准确率,而这样的预测器没有任何价值。那如何来解决机器学习中数据不平衡问题呢?这便是这篇文章要讨论的主要内容。

严格地讲,任何数据集上都有数据不平衡现象,这往往由问题本身决定的,但我们只关注那些分布差别比较悬殊的;另外,虽然很多数据集都包含多个类别,但这里着重考虑二分类,因为解决了二分类中的数据不平衡问题后,推而广之就能得到多分类情况下的解决方案。综上,这篇文章主要讨论如何解决二分类中正负样本差两个及以上数量级情况下的数据不平衡问题。

 

不平衡程度相同(即正负样本比例类似)的两个问题,解决的难易程度也可能不同,因为问题难易程度还取决于我们所拥有数据有多大。比如在预测微博互动数的问题中,虽然数据不平衡,但每个档位的数据量都很大——最少的类别也有几万个样本,这样的问题通常比较容易解决;而在癌症诊断的场景中,因为患癌症的人本来就很少,所以数据不但不平衡,样本数还非常少,这样的问题就非常棘手。综上,可以把问题根据难度从小到大排个序:大数据+分布均衡<大数据+分布不均衡<小数据+数据均衡<小数据+数据不均衡。对于需要解决的问题,拿到数据后,首先统计可用训练数据有多大,然后再观察数据分布情况。经验表明,训练数据中每个类别有5000个以上样本,数据量是足够的,正负样本差一个数量级以内是可以接受的,不太需要考虑数据不平衡问题(完全是经验,没有理论依据,仅供参考)。

二、如何解决

解决这一问题的基本思路是让正负样本在训练过程中拥有相同的话语权,比如利用采样与加权等方法。为了方便起见,我们把数据集中样本较多的那一类称为“大众类”,样本较少的那一类称为“小众类”。

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

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

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

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

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

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

这篇文章中我推荐了以下几个绩效标准,相比于传统的精确度,这些绩效标准可以更加深入地洞察模型的准确率:

  • 混淆矩阵:将要预测的数据分到表里来显示正确的预测(对角线),并了解其不正确的预测的类型(哪些类被分配了不正确的预测);
  • 精度:一种分类准确性的处理方法;
  • 召回率:一种分类完整性的处理方法;
  • F1分数(或F-分):精度和召回率的加权平均。

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

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

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

    3. 重新采样

    采样方法是通过对训练集进行处理使其从不平衡的数据集变成平衡的数据集,在大部分情况下会对最终的结果带来提升。

    采样分为上采样(Oversampling)下采样(Undersampling),上采样是把小种类复制多份,下采样是从大众类中剔除一些样本,或者说只从大众类中选取部分样本。

    随机采样最大的优点是简单,但缺点也很明显。上采样后的数据集中会反复出现一些样本,训练出来的模型会有一定的过拟合;而下采样的缺点显而易见,那就是最终的训练集丢失了数据,模型只学到了总体模式的一部分。

    上采样会把小众样本复制多份,一个点会在高维空间中反复出现,这会导致一个问题,那就是运气好就能分对很多点,否则分错很多点。为了解决这一问题,可以在每次生成新数据点时加入轻微的随机扰动,经验表明这种做法非常有效。

    因为下采样会丢失信息,如何减少信息的损失呢?第一种方法叫做EasyEnsemble,利用模型融合的方法(Ensemble):多次下采样(放回采样,这样产生的训练集才相互独立)产生多个不同的训练集,进而训练多个不同的分类器,通过组合多个分类器的结果得到最终的结果。第二种方法叫做BalanceCascade,利用增量训练的思想(Boosting):先通过一次下采样产生训练集,训练一个分类器,对于那些分类正确的大众样本不放回,然后对这个更小的大众样本下采样产生训练集,训练第二个分类器,以此类推,最终组合所有分类器的结果得到最终结果。第三种方法是利用KNN试图挑选那些最具代表性的大众样本,叫做NearMiss,这类方法计算量很大,感兴趣的可以参考“Learning from Imbalanced Data”这篇综述的3.2.1节。

    4. 数据合成

    数据合成方法是利用已有样本生成更多样本,这类方法在小数据场景下有很多成功案例,比如医学图像分析等。

    其中最常见的一种方法叫做SMOTE,它利用小众样本在特征空间的相似性来生成新样本。对于小众样本xi∈Sminxi∈Smin,从它属于小众类的K近邻中随机选取一个样本点x^ix^i,生成一个新的小众样本xnewxnew:xnew=xi+(x^−xi)×δxnew=xi+(x^−xi)×δ,其中δ∈[0,1]δ∈[0,1]是随机数。

    上图是SMOTE方法在K=6K=6近邻下的示意图,黑色方格是生成的新样本。

    SMOTE为每个小众样本合成相同数量的新样本,这带来一些潜在的问题:一方面是增加了类之间重叠的可能性,另一方面是生成一些没有提供有益信息的样本。为了解决这个问题,出现两种方法:Borderline-SMOTE与ADASYN。

    Borderline-SMOTE的解决思路是寻找那些应该为之合成新样本的小众样本。即为每个小众样本计算K近邻,只为那些K近邻中有一半以上大众样本的小众样本生成新样本。直观地讲,只为那些周围大部分是大众样本的小众样本生成新样本,因为这些样本往往是边界样本。确定了为哪些小众样本生成新样本后再利用SMOTE生成新样本。

    ADASYN的解决思路是根据数据分布情况为不同小众样本生成不同数量的新样本。首先根据最终的平衡程度设定总共需要生成的新小众样本数量GG,然后为每个小众样本xixi计算分布比例ΓiΓi:Γi=Δi/KZΓi=Δi/KZ,其中ΓiΓi是xixiK近邻中大众样本的数量,ZZ用来归一化使得∑Γi=1∑Γi=1,最后为小众样本xixi生成新样本的个数为gi=Γi×Ggi=Γi×G,确定个数后再利用SMOTE生成新样本。

    5. 加权

    除了采样和生成新数据等方法,我们还可以通过加权的方式来解决数据不平衡问题,即对不同类别分错的代价不同,如下图:

    kC(k,1)C(k,2)...0
     12...k
    10C(1,2)...C(1,k)
    2C(2,1)0......
    ...............

    横向是真实分类情况,纵向是预测分类情况,C(i,j)是把真实类别为j的样本预测为i时的损失,我们需要根据实际情况来设定它的值。

    这种方法的难点在于设置合理的权重,实际应用中一般让各个分类间的加权损失值近似相等。当然这并不是通用法则,还是需要具体问题具体分析。

    6. 一分类

    对于正负样本极不平衡的场景,我们可以换一个完全不同的角度来看待问题:把它看做一分类(One Class Learning)或异常检测(Novelty Detection)问题。这类方法的重点不在于捕捉类间的差别,而是为其中一类进行建模,经典的工作包括One-class SVM等。

    7. 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”的文章。

    8. 尝试名义变量模型

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

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

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

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

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

    9.  尝试从不同的观点进行思考

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

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

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

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

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

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

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

    10 . 尝试一些新的创意

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

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

     

    三、如何选择

    解决数据不平衡问题的方法有很多,上面只是一些最常用的方法,而最常用的方法也有这么多种,如何根据实际问题选择合适的方法呢?接下来谈谈一些我的经验。

    在正负样本都非常之少的情况下,应该采用数据合成的方式;在负样本足够多,正样本非常之少且比例及其悬殊的情况下,应该考虑一分类方法;在正负样本都足够多且比例不是特别悬殊的情况下,应该考虑采样或者加权的方法。

    采样和加权在数学上是等价的,但实际应用中效果却有差别。尤其是采样了诸如Random Forest等分类方法,训练过程会对训练集进行随机采样。在这种情况下,如果计算资源允许上采样往往要比加权好一些。

    另外,虽然上采样和下采样都可以使数据集变得平衡,并且在数据足够多的情况下等价,但两者也是有区别的。实际应用中,我的经验是如果计算资源足够且小众类样本足够多的情况下使用上采样,否则使用下采样,因为上采样会增加训练集的大小进而增加训练时间,同时小的训练集非常容易产生过拟合。对于下采样,如果计算资源相对较多且有良好的并行环境,应该选择Ensemble方法。

     

    四、更进一步

    什么样的模型需要 均衡的数据?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值