不平衡数据
2021-9-2
| 2023-8-6
0  |  阅读时长 0 分钟
type
status
date
slug
summary
tags
category
icon
password
Property
 
 
做分类算法训练时,如果训练集里的各个类别的样本数量不是大约相同的比例,就需要处理样本不平衡问题。不处理会怎么样呢?如果不处理,那么拟合出来的模型对于训练集中少样本的类别泛化能力会很差。一个二分类问题,如果训练集里A类样本占90%,B类样本占10%。 而测试集里A类样本占50%, B类样本占50%, 如果不考虑类别不平衡问题,训练出来的模型对于类别B的预测准确率会很低,甚至低于50%。
如何解决这个问题呢?
基本上有这几个策略:
  1. 增加数据。很多其它问题也都能用这个方法解决,但成本太高
  1. Oversampling和Undersampling,也有很多变种
  1. 划分训练集
  1. 改变评价指标
    1. 准确性悖论
      准确性悖论是一个矛盾的发现,即在预测分析中进行分类时,准确性并不是预测模型的良好指标。这是因为一个简单的模型可能具有很高的准确性,但过于粗糙而无用。例如,如果 A 类的发生率占主导地位,在 99% 的案例中被发现,那么预测每个案例都是 A 类的准确率将达到 99%。 在这种情况下,精确率和召回率是更好的衡量标准。根本问题是正类和负类之间存在类不平衡。这些类别的先验概率需要在错误分析中加以考虑。精度和召回率有帮助,但精度也可能会受到测试集中非常不平衡的类先验的影响。
  1. 算法层面
      • 改变 cost function,sklearn 很多方法可以输入 weights 参数,实际上就是改变 cost function,让稀有类的权重增加。
      • 使用可以处理不平衡问题的模型,如朴素贝叶斯。
      • 对于可以重复训练的模型,把多数类分割成多个部分,每部分都和稀有类结合起来去训练模型。
      • 考虑不同误分类情况代价的差异性对算法进行优化,主要是基于代价敏感学习算法(Cost-Sensitive Learning),代表的算法有adacost;
 

权重法

权重法是比较简单的方法,对训练集里的每个类别加一个权重class weight。如果该类别的样本数多,那么它的权重就低,反之则权重就高。如果更细致点,还可以对每个样本加权重sample weight,思路和类别权重也是一样,即样本数多的类别样本权重低,反之样本权重高。sklearn中,绝大多数分类算法都有class weight和 sample weight可以使用。
 

采样法

采样法常用的也有两种思路:
  • 一种是对类别样本数多的样本做子采样, 比如训练集里A类别样本占90%,B类别样本占10%。那么可以对A类的样本子采样,直到子采样得到的A类样本数和B类别现有样本一致为止,这样就只用子采样得到的A类样本数和B类现有样本一起做训练集拟合模型。
  • 第二种思路是对类别样本数少的样本做过采样,对B类别的样本做过采样,直到过采样得到的B类别样本数加上B类别原来样本一起和A类样本数一致,最后再去拟合模型。
上述两种常用的采样法很简单,但是都有个问题,就是采样后改变了训练集的分布,可能导致泛化能力差。所以有的算法就通过其他方法来避免这个问题,比如SMOTE算法通过人工合成的方法来生成少类别的样本。方法也很简单,对于某一个缺少样本的类别,它会随机找出几个该类别的样本,再找出最靠近这些样本的若干个该类别样本,组成一个候选合成集合,然后在这个集合中不停的选择距离较近的两个样本,在这两个样本之间,比如中点,构造一个新的该类别样本。举个例子,比如该类别的候选合成集合有两个样本 ,那么SMOTE采样后,可以得到一个新的训练样本 ,通过这种方法可以得到不改变训练集分布的新样本,让训练集中各个类别的样本数趋于平衡。可以用imbalance-learn这个Python库中的SMOTEENN类来做SMOTE采样
 

Oversampling

RandomOverSampler

  • 优点:简单
  • 缺点:小众样本复制多份,一个点会在高维空间中反复出现。导致过拟合,或者运气好就能分对很多点,否则分错很多点
 

SMOTE

随机选取少数类的样本,在该样本与最邻近的样本的连线上随机取点,生成无重复的新的稀有类样本
缺点:
  • 增加了类之间重叠的可能性(由于对每个少数类样本都生成新样本,因此容易发生生成样本重叠(Overlapping)的问题),
  • 生成一些没有提供有益信息的样本

ADASYN

关注的是在那些基于KNN分类器被错误分类的原始样本附近生成新的少数类样本

Undersampling

RandomUnderSampler

  • replacement = True 有放回抽样,结果会有重复,默认 replacement = False
  • 启发式规则做降采样 under_sampling.NearMiss(version=1) version = 1, 2, 3 有3种启发式规则
  • 用近邻算法进行降采样 under_sampling.EditedNearestNeighbours() 绝大多数(kind_sel=’mode’)或者全部(kind_sel=’all’)的近邻样本都属于同一个类,这些样本会被保留在数据集中
  • 在EditedNearestNeighbours基础上, 延伸出了RepeatedEditedNearestNeighbours算法和ALLKNN算法,前者重复基础的EditedNearestNeighbours算法多次,后者在进行每次迭代的时候,最近邻的数量都在增加。
  • under_sampling.ClusterCentroids() 不是从原始数据集中直接抽取数据,每一个类别的样本都会用K-Means算法的中心点来进行合成。

组合采样

SMOTE可以通过在边际异常值和内点之间插入新点来生成噪声样本, 这个问题可以通过清除过度采样产生的空间来解决。
用于组合过采样和欠采样方法的两个工具是:SMOTETomek 和SMOTEENN。
SMOTEENN倾向于清除比SMOTETomek更多的噪声样本。
 
 
 
 
  • Scikit-Learn
  • 字符串操作不平衡分类的k折交叉验证
    目录