精华内容
下载资源
问答
  • 2021-02-23 16:23:31

    样本不平衡其实的主要思想就是过采样和欠采样,但是由于在复制少量标签的样本或者筛选大量标签的样本方法不同衍生出了不同的处理手段

     

    1.随机过采样:复制标签少的样本使得好坏比满足建模需要

    2.随机欠采样:抽取标签多的样本使得好坏比满足建模需要 (会丢失样本信息)

    3.EasyEnsemble:标签多的样本进行n份,每份都和标签少的全部样本组合成n份训练样本,利用集成学习训练n个弱分类器(原论文是用adaboost框架,当然用其他框架也是可以的)

    4.BalanceCascade:对标签多的样本进行欠采样,和标签少的全部样本组合成训练样本,弱分类器分类正确的标签多数样本不放回,分类错误的放回。

    再进行标签多的样本欠采样,训练。

    举个例子吧。假设你有1000个标签为1的样本,10个标签为0的样本。

    第一步,从1样本中随机抽取10个和10个0样本组成训练样本

    第二步,训练弱分类器发现,10个1样本中7个分类正确,3个分类错误。

    第三步,将3个分类错误的1样本放回原来的990个1样本中。

    重复第一步(这个时候抽样的1样本总样本量为993个)

    5. KNN 欠抽样:虽然有很多变种,其实思想是大同小异的。

    5.1 NM欠采样:有3个不同的方法

    • NearMiss-1从多数类中选择,那些与少数类中三个最接近示例的平均距离最小的示例。
    • NearMiss-2从多数类中选择,那些与从少数类中三个最远示例的平均距离最小的示例。
    • NearMiss-3涉及为少数类中最接近的每个示例,选择给定数量的多数类示例。

    举个栗子,假设你有1000个标签为1的样本,10个标签为0的样本

    NearMiss-1就是每个1样本去找到离他最近的3个0样本(欧氏距离),计算平均距离。然后选取平均距离小的n个1样本(满足建模的好坏样本比就可以)

    NearMiss-2就是每个1样本去找到离他最远的3个0样本,计算平均距离。选取平均距离最小的n个1样本

    NearMiss-3就是考虑每个0样本,去找到距离0样本最近的n个样本,组成训练样本

    可以熟悉下下面这个库的使用

    imblearn.under_sampling import NearMiss

    5.2 浓缩最近邻(Condensed Nearest Neighbor(CNN))规则欠采样

    栗子还是那个栗子

    第一步,保留全部标签为0的样本

    第二步,基于所有1样本和0样本对1样本进行knn(K=1)训练

    第三步,保留分类错误的1样本

    第四步,全部0样本和分类错误的1样本组成采样后的样本

    这样会让0,1样本比较接近的样本放在一起,有利于进行边界决策,距离太远就不用考虑啦,要是能训练出区分这些比较接近的样本的模型才是重点。

    5.3 Tomek链接的欠采样

    CNN欠采样的变种,目的是清除边界上的样本,一些分布非常相似但是标签模棱两可的样本

    Tomek链接定义:

    (i)实例a的最近邻居是b,(ii)实例b的最近邻居是a,并且(iii)实例a和b属于不同的类,则实例a和b定义Tomek链接

    将有Tomek链接的样本删除组成训练样本

    Tomek的目的是剔除边界上的样本,但是并不是一个特别好用的欠采样技术,一般是结合其他欠采样方法如CNN使用(OSS单面选择欠采样)

     

    5.4 编辑最近邻(Edited Nearest Neighbors (ENN))规则欠采样

    也是一个脑洞非常神奇的采样设计,目的是剔除边界样本

    先用K=3对1样本进行分类,将分类错误的1样本剔除,再结合CNN(K=1)采样

    5.5 欠采样的邻居清洁规则(NCR)

    其实就是先用CNN再用ENN

    参考文献https://zhuanlan.zhihu.com/p/154266607

    总结一下

    KNN进行欠采样其实关注的就是两个点

    1. 清除离边界很远的冗余样本

    2.清除离边界很近的模糊样本

     

    6. SMOTE算法过采样

    不复杂,对于0样本找到最近的0样本,或者随机最近的n个0样本中的一个

    然后对于两个0样本x差值中间随机选一个值生成新的0样本

    比如 0样本1的 x1 = 1 , 0样本1的x1 = 4

    那么生成的0样本 x1 = (4-1) * rand(0,1) + 1

    保证生成的0样本的x取值在两个样本之间就可以了

     

    7.Borderline-SMOTE算法

    SMOTE算法的一种优化,对于哪些0样本选取作为基准来进行生成新的0样本

    如果说0样本周围k个样本中50%以上都是1样本,而且不是100%都是1样本(如果100%的话会被认为是噪声),就选取这个0样本进行SMOTE插值

    参考文献:https://blog.csdn.net/qq_27802435/article/details/81201357?ops_request_misc=&request_id=&biz_id=102&utm_term=knn%E6%AC%A0%E9%87%87%E6%A0%B7&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-5-81201357.first_rank_v2_pc_rank_v29

    8. KMeans过采样

    第一步,对1样本和0样本分别进行KMeans聚类

    第二步,对于样本少的类别进行过采样(解决内部不平衡问题)

    第三步,对于1样本和0样本进行过采样(解决样本标签不平衡问题)

    更多相关内容
  • 结合k-均值聚类缓解行人检测正负样本不平衡问题.pdf
  • 样本不平衡的解决方案(很详细)

    千次阅读 2022-03-21 21:15:30
    样本不平衡的影响2. 可尝试的改进方案2.1 采样2.2 数据增强2.3 loss2.4 模型层面2.5 评估指标 1. 样本不平衡的影响 ​ 举个例子,在广告CTR预估场景中,正负样本的占比可以达到1:500,点击的正样本是少数类,没...

    1. 样本不平衡的影响

    ​ 举个例子,在广告CTR预估场景中,正负样本的占比可以达到1:500,点击的正样本是少数类,没点击的负样本为多数类。如果直接拿这个比例去训练模型的话,很容易学出一个把所有样本都预测为负的模型,因为喂进去学习的样本大多都是负样本。这种情况下,损失会很低,准确率一般都会很高,比如0.98,但是F1会很低,比如0.01。你可以理解为,模型最终学习的并不是如何分辨正负,而是学到了“负远比正的多“这样的先验信息,凭着这个信息模型就会把所有的样本都判定为负。

    ​ 所有,样本不均衡带来的影响就是模型会学习到训练空间中样本比例的差距,或差距悬殊这种先验信息,以致于实际预测时就会对多数类别有侧重。

    本文以正样本为少数类、负样本为多数类进行阐述。

    对于简单线性可分任务,样本不均衡的影响不会很大。

    2. 可尝试的改进方案

    2.1 采样

    • 正样本过采样
      • 如果随机的复制多分正样本进行过采样,那么必然会导致过拟合,因为训练数据中的正样本会反复出现。这种做法不建议。
    • 正样本smote
      • smote是一种合成采样的方法,它主要基于少数样本,计算样本空间之间的相似度,然后创建人工合成样本,大致流程如下:
      • 1.对于正样本(少数类) S m i n ∈ S S_{min} ∈ S SminS 中的样本,即 x i ∈ S m i n x_i ∈ S_{min} xiSmin,计算它的K个近邻;
      • 2.通过计算欧式距离,得到距离 x i x_i xi最近的K个 S m i n S_{min} Smin中的样本数据;
      • 3.然后从K个近邻中,随机选择一个样本,产生人工合成的数据,K和KNN中的含义一致,属于超参;
      • 4. x n e w = x i + ( x ^ i − x i ) ∗ δ x_{new} = x_i + (\hat x_i - x_i) * \delta xnew=xi+(x^ixi)δ,其中, x ^ i \hat x_i x^i x i x_i xi的其中一个近邻, δ ∈ [ 0 , 1 ] \delta ∈ [0, 1] δ[0,1]是一个随机数。
      • smote的方法也可能会造成过拟合,除了常用的smote之外,还有自适应合成采样,比如Borderline-SMOTE、Adaptive Synthetic Sampling(ADA-SYN),请参考:https://blog.csdn.net/hren_ron/article/details/81172044
    • 负样本欠采样
      • 在负样本空间中,随机的不放回的丢掉一些样本。
      • 因为欠采样会丢掉信息,所以可以通过Ensemble、Boosting的思想来进行欠采样。
    • EasyEnsemble
      • 利用模型融合的方法(Ensemble):多次下采样(放回采样,这样产生的训练集才相互独立)产生多个不同的训练集,进而训练多个不同的分类器,通过组合多个分类器的结果得到最终的结果。
    • BalanceCascade
      • 利用增量训练的思想(Boosting):先通过一次下采样产生训练集,训练一个分类器,对于那些分类正确的大众样本不放回,然后对这个更小的大众样本下采样产生训练集,训练第二个分类器,以此类推,最终组合所有分类器的结果得到最终结果。
    • 在计算性能足够的情况下,可以考虑数据分布的信息,通常是基于距离的邻域关系的采样方法,如ENN、NearMiss等,这里不过多介绍。

    2.2 数据增强

    数据增强是指从原始数据中加工出更多的数据表示,提高原数据的数量和质量,从而提高模型的学习效果。

    • 基于样本变换的数据增强
      • 单样本增强:主要用于图像,比如几何操作、颜色变换、随机查出、剪切旋转等等,可参见imgaug开源库。
      • 多样本增强:是指通过组合及转换多个样本的方式,比如刚刚提到的smote,还有SamplePairing、Mixup等方法在特征空间内构造已知样本的邻域值样本。
    • 基于深度学习的数据增强
      • 生成模型,如变分自编码网络(VAE)和生成生成对抗网络(GAN),其生成样本的方法也可以用于数据增强,这种基于网络合成的方法相比于传统的数据增强技术虽然过程复杂,但是生成的样本更加多样。

    不论是过采样还是欠采样,都会引入噪声,导致过拟合,可以通过类似Pu-Learning半监督的思路选择增强数据的较优子集,以提高模型的泛化能力。

    2.3 loss

    loss层面的主流就是常用的代价敏感学习,为不同的分类错误给予不同惩罚力度(权重),在调解类别平衡的同时,也不会增加计算复杂度。即对类别比例小的样本给更大的权重系数,对类别比例大的样本给更小的权重系数,通过这种方式可以在一定程度上解决正负样本不均衡的问题。

    • class weight

      • class weight可以为不同类别的样本提供不同的权重,少数类的正样本有更高的权重,从而模型可以平衡各类别的学习。如sklearn实现如下,类别权重除了设定为balanced外,还可以作为超参调试,避免决策边界偏重多数类的现象

      • model = LogisticRegression(class_weight={0:1,1:10})  # 代价敏感学习
        
      • import torch
        pos_weight = num_neg / num_pos
        torch.mean(pos_weight * y_true * -torch.log(y_pred) + (1 - y_true) * -torch.log(1 - y_pred))
        
      • import torch.nn as nn
        loss_fn = nn.CrossEntropyLoss(weight=[1,2,1])
        loss = loss_fn(output, label)
        
    • OHEM、Focal Loss

      • 类别不平衡可以归结为难易样本不平衡,而难易样本不平衡可以归结为梯度不平衡。OHEM和Focal Loss都做了两件事:难样本挖掘以及类别的平衡。
      • OHEM算法的核心是选择一些难样本(多样性和高损失的样本)作为训练样本,针对性的改善模型学习效果。对于数据类别不平衡问题,OHEM的针对性更强。
      • Focal Loss的核心思想是在交叉熵的基础上增加了类别的不同权重以及困难样本的权重,以改善模型学习效果。
      • 另外还有GHM、PISA等方法,可自行了解。
      • 关于Focal loss详细请看:https://blog.csdn.net/qq_42363032/article/details/121573416

    2.4 模型层面

    模型方面可以选择对不均衡比较不敏感的算法,例如树模型、以及集成树模型的方法。因为树模型是按照增益递归的划分数据,划分过程考虑的是局部的增益,全局样本是不均衡,但是局部空间不一定,所以比较不敏感一些些。当然这不是绝对的,相关实验可见https://arxiv.org/abs/2104.02240

    解决不均衡问题,更为优秀的是基于采样+集成树模型等方法,可以在类别不均衡数据上表现良好。

    • BalanceCascade
      • 上面也提到过,论文原文使用Adaboost作为基分类器,这里在过多啰嗦一下。
      • 核心思路就是在每一轮训练时都使用多数类与少数类数量上相等的训练集,然后使用该分类器对全体多数类进行预测,通过控制分类阈值来控制FP,将所有判断正确的删除,保留误判的,然后进入下一轮迭代继续降低多数类数量。
    • EasyEnsemble
      • 论文原文也是基于Adaboost作为基分类器,核心思路就是将多数类样本集随机分成 N 个子集,且每一个子集样本与少数类样本相同,然后分别将各个多数类样本子集与少数类样本进行组合,使用基分类模型进行训练,最后bagging集成各基分类器,得到最终模型。

    通常,在数据集噪声较小的情况下,可以用BalanceCascade,可以用较少的基分类器数量得到较好的表现(基于串行的集成学习方法,对噪声敏感容易过拟合)。

    噪声大的情况下,可以用EasyEnsemble,基于串行+并行的集成学习方法,bagging多个Adaboost过程可以抵消一些噪声影响。

    此外还有RUSB、SmoteBoost、balanced RF等其他集成方法可以自行了解。

    • 还可以将二分类看成一分类或异常检测问题

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

      • # 一分类svm
        from sklearn.svm import OneClassSVM
        # 孤立森林异常检测
        from sklearn.ensemble import IsolationForest
        
    • imbalance-XGBoost

      • 这是一个有关不平衡样本的XGB库,它在XGB上集成了focal loss和代价敏感学习。官网如下:https://github.com/jhwjhw0123/Imbalance-XGBoost

      • # pip install imbalance-xgboost
        
        from imxgboost.imbalance_xgb import imbalance_xgboost as imb_xgb
        
        # ----------
        base = imb_xgb(special_objective='focal', focal_gamma=focal_gamma)
        base.fit(x_train, y_train)
        print('base fit over')
        y_test_preba = base.predict_sigmoid(x_test)
        
        # ----------
        base = imb_xgb(special_objective='weighted', imbalance_alpha=imbalance_alpha)
        base.fit(x_train, y_train)
        print('base fit over')
        y_test_preba = base.predict_sigmoid(x_test)
        

    2.5 评估指标

    机器学习正负样本失衡时的评估指标参考,及代码实现:

    https://blog.csdn.net/qq_42363032/article/details/121560262




    参考:

    https://blog.csdn.net/u011414200/article/details/50664266

    https://blog.csdn.net/qq_42363032?type=blog

    展开全文
  • - 为什么样本不平衡时会出现问题 - 样本不平衡的处理方式 - 样本不平衡时算法的评价指标

    为什么训练数据不平衡时会出现问题?

      数据不平衡问题主要存在于有监督机器学习任务中。当遇到不平衡数据时,以总体分类准确率为学习目标的传统分类算法会过多地关注多数类,从而使得少数类样本的分类性能下降,所以绝大多数常见的机器学习算法对于不平衡数据集都不能很好地工作。

      总结来说,出现样本不平衡问题的本质原因是模型在训练时优化的目标函数和在测试时使用的评价标准不一致。这种“不一致”可能是由于:

    1、 训练数据的样本分布与测试时期望的不一样。

    例如,训练时优化的是整个训练集(正负样本比例可能是1:99)的正确率,而测试时可能想要模型在正样本和负样本上的平均正确率尽可能大(实际上期望正负样本比例是1:1)。

    2、 训练阶段不同类别的权重与测试阶段不一致。

    例如,训练时认为所有样本的贡献是相等的,而测试时假阳性样本和假阴性样本有着不同的代价。

    样本不平衡的处理方式

      一般可以从以下角度来处理样本不平衡问题:数据采样、算法模型。

    A. 数据采样

      采样分为过采样和欠采样,过采样是把小众类复制多份,欠采样是从大众类中剔除一些样本,或者说只从大众类中选取部分样本。

    1.欠采样

    1.1 随机欠采样

      欠采样是从多数类样本中随机选择(有放回或无放回)少量样本,再合并原有少数类样本作为新的训练数据集。

    通过设置RandomUnderSampler中的replacement=True参数, 可以实现自助法(boostrap)抽样。

    优点:

    • 平衡数据的同时减小了数据量,可加速训练,尤其是当样本集规模很大的时候。

    缺点:

    • 数据减少会影响模型的特征学习能力和泛化能力:丢弃一些样本,可能会损失部分有用的信息,造成模型只学到了整体模式的一部分。

    1.2 Informed Undersampling

      对于欠采样,可以采用 Informed Undersampling 来解决由于随机欠采样带来的数据丢失问题。常见的Informed Undersampling 算法有:Easy Ensemble、Balanced Cascade、NearMiss、One-sided Selection等算法。

    1.2-1 Easy Ensemble

      基本思想是:每次从多数类样本 S m a x S_{max} Smax 中随机抽取一个子集 E E E ∣ E ∣ = ∣ S m i n ∣ |E|=|S_{min}| E=Smin),然后用数据集 E + S m i n E+S_{min} E+Smin 训练一个分类器。重复上述过程若干次,得到多个分类器,最终分类结果是这几个分类器的融合。

    在这里插入图片描述

    from imblearn.ensemble import EasyEnsemble
    

    1.2-2 Balanced Cascade

      Balanced Cascade利用增量训练的思想:在每一级中从多数类 S m a x S_{max} Smax 中随机抽取子集 E E E,用 E + S m i n E+S_{min} E+Smin 训练该级的分类器,然后将 S m a x S_{max} Smax 中能被当前分类器正确判别的样本剔掉,继续下一级的操作,重复若干次得到级联结构,最终的输出结果也是各级分类器结果的融合。
    在这里插入图片描述

    from imblearn.ensemble import BalanceCascade
    

    1.2-3 NearMiss

      NearMiss本质上是一种原型选择(prototype selection)方法,即从多数类样本中选取最具代表性的样本用于训练,主要是为了缓解随机欠采样中的信息丢失问题。NearMiss采用一些启发式的规则来选择样本,根据规则的不同可分为3类:

    • NearMiss-1:选择到最近的K个少数类样本平均距离最近的多数类样本
    • NearMiss-2:选择到最远的K个少数类样本平均距离最近的多数类样本
    • NearMiss-3:对于每个少数类样本选择K个最近的多数类样本,目的是保证每个少数类样本都被多数类样本包围

    缺点:

    • NearMiss-1和NearMiss-2的计算开销很大,因为需要计算每个多类别样本的K近邻点。
    • NearMiss-1易受离群点的影响,相比之下NearMiss-2和NearMiss-3不易产生这方面的问题。
    from imblearn.under_sampling import NearMiss
    

    2. 过采样

    2.1 随机过采样

      过采样是从少数类样本集中随机重复抽取样本(有放回)以得到更多样本。

    from imblearn.over_sampling import RandomOverSampler
    

    优点:

    • 没有导致数据信息损失,实际操作中一般效果也好于欠采样。

    缺点:

    • 扩大了数据规模,增加了模型训练的复杂度,容易造成过拟合。

    2.2 数据扩充

      对少数类样本进行一些噪声扰动或换边以构造出新的样本。

    2.3-1 SMOTE(Synthetic Minority Oversampling Technique,合成少数类过采样技术)

    在这里插入图片描述

    a. 对少数类中每一个样本 x i x_i xi,以欧氏距离为标准计算它到少数类样本集中所有样本的距离,得到其 k k k 个近邻: x d 1 , x d 2 , ⋯   , x d k x_{d_1},x_{d_2},\cdots,x_{d_k} xd1,xd2,,xdk

    b. 根据样本不平衡比例设置一个采样比例以确定采样倍率 N N N,对于每一个少数类样本 x i x_i xi,从其 k k k 近邻中随机选择若干个样本;

    c. 对于每一个随机选择出来的近邻 x ^ i \hat{x}_i x^i,分别与原样本按照公式 x n e w = x i + r a n d ( 0 , 1 ) × ( x ^ i − x i ) x_{new}=x_i+rand(0,1)\times (\hat{x}_i-x_i) xnew=xi+rand(0,1)×(x^ixi)生成新样本。

    from imblearn.over_sampling import SMOTE
    

    优点:

    • 通过人工构造相似样本取代直接复制的方法减弱了过拟合,也没有丢失有用的信息。

    缺点:

    • 在数据维度很高时,效率很低;
    • 人工合成样本时没有考虑近邻样本可能来自不同类别,导致增大类别间重叠;
    • 为每一个少数类样本合成相同数量的新样本,可能会增大类间重叠率,并且会生成一些不能提供有益信息的样本。

    2.3-2 Borderline-SMOTE

      Borderline-SMOTE对SMOTE作了改进,只给那些处在分类边界上的少数类样本合成新样本。具体地:将少数类样本分为三类,

    • safe:选取的少数类样本周围也都是少数类样本,新合成的样本不会提供太多有用信息。
    • noise:选取的少数类样本周围都是多数类样本,这类的样本可能是噪音,新合成的样本会与周围的多数类样本产生大部分重叠,致使分类困难。
    • danger:近邻样本中超过一半为多数类样本。

      处于”danger“状态的样本代表靠近”边界“附近的少数类样本,而处于边界附近的样本往往更容易被误分类。Border-line SMOTE算法只会从处于”danger“状态的样本中随机选择,然后用SMOTE算法产生新的样本。

    在这里插入图片描述
    Border-line SMOTE 分为两种:

    • Borderline-1 SMOTE:在合成样本时选出的 k 近邻样本 x ^ i \hat{x}_i x^i 是一个少数类样本;
    • Borderline-2 SMOTE:在合成样本时选出的 k 近邻样本 x ^ i \hat{x}_i x^i 可以是任意类别 。

    2.4 ADASYN,自适应合成抽样

    a. 计算需要合成的样本数量:
    G = ( m l − m s ) × β G=(m_l-m_s)\times \beta G=(mlms)×β

    其中, m l m_l ml 是多数类样本数量, m s m_s ms 是少数类样本数量, β ∈ [ 0 , 1 ] \beta\in [0,1] β[0,1] 为随机数,若 β = 1 \beta=1 β=1,采样后正负比例为 1:1。

    b. 对每个少数类样本 x i , i = 1 , 2 , , ⋯ m s x_i,i=1,2,,\cdots m_s xi,i=1,2,,ms,计算 k k k 近邻中多数类占比: r i = Δ i / k r_i=\Delta_i/k ri=Δi/k。其中 Δ i \Delta_i Δi k k k 近邻中多数类样本数。

    c. 对 r i r_i ri 标准化:
    r ^ i = r i / ∑ i = 1 m s r i \hat{r}_i=r_i/\sum_{i=1}^{m_s}r_i r^i=ri/i=1msri

    d. 根据样本权重,计算每个少数类样本需生成的样本数: g i = r ^ i × G g_i=\hat{r}_i\times G gi=r^i×G

    e. 对每个少数类样本 x i x_i xi,根据SMOTE算法生成样本: x n e w = x i + r a n d ( 0 , 1 ) × ( x d i − x i ) x_{new}=x_i+rand(0,1)\times (x_{d_i}-x_i) xnew=xi+rand(0,1)×(xdixi)。其中, x d i x_{d_i} xdi x i x_i xi k k k 近邻中随机选取的一个少数类样本。

      ADASYN利用分布 r ^ i \hat{r}_i r^i 来自动决定每个少数类样本所需要合成的样本数量,这等于是给每个少数类样本施加了一个权重,周围的多数类样本越多则权重越高。

    from imblearn.over_sampling import ADASYN
    

    缺点:

    • 易受离群点的影响。

    3. 基于聚类的采样

    a. 对不同的类别分别进行聚类,一般样本较多的类聚类中心数目较多;

    b. 对每个分别类进行过采样或欠采样,使得原始类别中所有cluster有相同数目的样本。

    优点:

    • 缓解类间、类内不平衡问题;

    缺点:

    • 容易使模型对训练数据过拟合。

    B. 算法

    1. 改变模型训练时的目标函数

      改变模型训练时的目标函数来矫正这种不平衡性。例如代价敏感学习中不同类别不同权重。模型上选对样本不均衡问题不敏感的模型,如决策树;或者调整分类阈值,使得更倾向与类别少的数据。

    2. 问题转化

      样本数目极不平衡时,将问题转化为单类学习(One Class Learning)、异常检测(Novelty Detection)。

      异常点检测的目的是找出数据集中和大多数数据不同的数据。常见的异常点检测算法有三种情况:一是在做特征工程的时候需要对异常的数据做过滤,防止对归一化等处理的结果产生影响;二是对没有标记输出的特征数据做筛选,找出异常的数据;三是对有标记输出的特征数据做二分类时,由于某些类别的训练样本非常少,类别严重不平衡,此时也可以考虑用非监督的异常点检测算法来做。

    无监督︱异常、离群点检测 一分类——OneClassSVM
    异常点检测算法小结

    one-class SVM

    在这里插入图片描述

      One Class SVM 是指你的训练数据只有一类正(或者负)样本的数据, 而没有另外的一类。在这时,你需要学习的实际上你训练数据的边界,此时不能使用最大化软边缘了,因为没有两类的数据。假设最好的边缘要远离特征空间中的原点。左边是在原始空间中的边界,可以看到有很多的边界都符合要求,但是比较靠谱的是找一个比较紧的边界(红色的)。这个目标转换到特征空间就是找一个离原点比较远的边界,同样是红色的直线。当然这些约束条件都是人为加上去的,你可以按照你自己的需要采取相应的约束条件,比如让你data 的中心离原点最远。

      利用One-Class SVM,它有能力捕获数据集的形状,因此对于强非高斯数据有更加优秀的效果,例如两个截然分开的数据集。严格来说,一分类的SVM并不是一个异常点监测算法,而是一个奇异点检测算法:它的训练集不能包含异常样本,否则的话,可能在训练时影响边界的选取。但是,对于高维空间中的样本数据集,如果它们做不出有关分布特点的假设,One-class SVM将是一大利器。

    样本不平衡时算法的评价指标

    在这里插入图片描述

      ROC曲线和PR(Precision - Recall)曲线皆为类别不平衡问题中常用的评估方法。

    ROC

    优点:

    • 兼顾正例和负例的权衡。因为TPR聚焦于正例,FPR聚焦于与负例,使其成为一个比较均衡的评估方法。
    • ROC曲线选用的两个指标都不依赖于具体的类别分布。TPR用到的TP和FN同属P列,FPR用到的FP和TN同属N列,所以即使P或N的整体数量发生了改变,也不会影响到另一列。

    缺点:
    在类别不平衡的背景下,负例的数目众多致使FPR的增长不明显,导致ROC曲线呈现一个过分乐观的效果估计。ROC曲线的横轴采用FPR,根据FPR = FP/N = FP/(FP+TN),当负例N的数量远超正例P时,FP的大幅增长只能换来FPR的微小改变。结果是虽然大量负例被错判成正例,在ROC曲线上却无法直观地看出来。

    PR

    • Precision使用的TP和FP就分属两列,则易受类别分布改变的影响。负例的大幅增长将带来PR曲线的大幅下降。
    • PR曲线的两个指标都聚焦于正例。类别不平衡问题中由于主要关心正例,所以在此情况下PR曲线被广泛认为优于ROC曲线。

    机器学习之类别不平衡问题 (3) —— 采样方法
    机器学习之类别不平衡问题 (2) —— ROC和PR曲线
    机器学习中的样本不平衡问题
    怎样解决样本不平衡问题
    不平衡数据处理之SMOTE、Borderline SMOTE和ADASYN详解及Python使用
    easy ensemble 算法和balance cascade算法

    深度学习:
    深度学习 | 分类任务中类别不均衡解决策略
    【经验】keras中处理数据不平衡问题的方法|Keras官方文档

    展开全文
  • [机器学习] XGBoost 样本不平衡问题

    千次阅读 2021-05-06 16:51:43
    在用xgboost训练二分类模型时,除了直接使用过采样和下采样,xgboost接口还提供一些处理不平衡数据的方法,有scale_pos_weight参数的设置,还有给样本赋予一定的权重。接下来让我们仔细看一下吧~ 参数scale_pos_...

    一 样本不平衡

    何谓样本不平衡——简单来说就是数据集中负样本的数量远远大于正样本的数量。在这个情况下,模型就会倾向于把样本预测为负样本,因为这是最便捷的降低损失、提高模型准确率的方法。例如:有一个正样本数量为1,负样本数量为99的数据集,模型就算无脑地把全部样本预测为负样本也能达到99%的准确度,试想有这么一个分类器,每次我们把数据喂‘给它时,在不调整阈值的情况下,它都倾向于把测试集的样本预测为负样本,你觉得这样的分类器还会是一个好的分类器吗?

    在对不平衡数据进行训练时,通常会考虑一下怎么处理不平衡数据能使训练出来的结果较好。

    在用xgboost训练二分类模型时,除了直接使用过采样和下采样,xgboost接口还提供一些处理不平衡数据的方法,有scale_pos_weight参数的设置,还有给样本赋予一定的权重。接下来让我们仔细看一下吧~

    参数scale_pos_weight:

    XGBoost中存在着调节样本不平衡的参数scale_pos_weight,通常我们在参数中输入的是负样本量与正样本量之比

    底层原理:通过scale_pos_weight改变了正负样本的权重,进而改变了正负样本损失函数的大小,最终改变了样本的概率预测值 wi。

    For common cases such as ads clickthrough log, the dataset is extremely imbalanced. This can affect the training of xgboost model, 
    and there are two ways to improve it.
      If you care only about the ranking order (AUC) of your prediction
          Balance the positive and negative weights, via scale_pos_weight
          Use AUC for evaluation
      If you care about predicting the right probability
          In such a case, you cannot re-balance the dataset
          In such a case, set parameter max_delta_step to a finite number (say 1) will help convergence
    

    官方的解释是这样的,scale_pos_weight 可以设置为数据中负样本数量/正样本数量

    if (info.labels[i] == 1.0f) w *= param_.scale_pos_weight

    scale_pos_weight 是用来调节正负样本不均衡问题的,用助于样本不平衡时训练的收敛。

    scale_pos_weight = 负样本总数/正样本总数 。若训练负样本总数是500 ,正样本总数100,那么设置 scale_pos_weigh为 5 。

     

    常见的情况比如广告点击日志,数据集是极其不平衡的,导致训练的xgboost模型受到影响,有两种方法可以改善:

    1)  如果仅仅关注预测问题的AUC指标,那么你可以调节 scale_pos_weight参数来帮助训练数据不平衡带来的收敛问题 。

    2)如果关注预测概率的准确性问题,那么你就不能调节scale_pos_weight参数来改变样本权重的方法帮助收敛,可通过设置参数 max_delta_step 为一个有限的值来帮助收敛 。


    如何你仅仅关注预测问题的排序或者AUC指标,那么你尽管调节此参数。如果你希望得到真正的预测概率则不能够通过此参数来平衡样本。什么意思呢,让我们来举个例子:加入我们现在需要通过体重来预测男女,有三个人体重分别为50kg、60kg、70kg。假设他们是男生的真正概率是:0.4、0.6、0.8。那么好,我现在模型预测出的概率为:0.7、0.8、0.9。如果讲预测概率的话,显然模型效果很差,但是我们预测的男生概率的排序以及 ROU 曲线(包括对应 AUC 值)都不会改变。

     关于scale_pos_weight ,在xgboost里边的源码是

              bst_float w = _is_null_weight ? 1.0f : _weights[_idx];
              bst_float label = _labels[_idx];
              if (label == 1.0f) {
                w *= _scale_pos_weight;
              }
              if (!Loss::CheckLabel(label)) {
                // If there is an incorrect label, the host code will know.
                _additional_input[0] = 0;
              }
              # 改变了损失函数,即改变了损失函数的一阶导和二阶导大小,落到每个叶结点的概率预测值也随之改变。
              _out_gpair[_idx] = GradientPair(Loss::FirstOrderGradient(p, label) * w,
                                              Loss::SecondOrderGradient(p, label) * w);
            },
    
    
    # 见源码 src/objective/regression_obj.cu

    从源代码也可以看出,scale_pos_weight其实就是改变样本weight,也就是和在DMatrix里边设置每个样本的weight是一样的。

    在DMatrix里边设置每个样本的weight 是怎样改变训练过程的呢,其实是改变训练的损失函数,源代码里的代码如下,可以看到对不同的样本赋予不同的权重实际上是影响了该样本在训练过程中贡献的损失,进而改变了一阶导和二阶导。

    其中​是损失函数关于上一棵树的预测值的的一阶导,​是损失函数关于上一棵树的预测值的二阶导,当正样本的损失函数发生改变,相应的叶子节点的预测值也会发生改变。

    本质上说,scale_pos_weight参数也是通过调节样本的预测概率值来改变预测结果,当我们需要提高模型的评估标准 ——如 auc、召回率recall的大小等,可以通过调整scale_pos_weight参数达到我们的目的;但是,假如需要确切了解每个样本为正样本的可能性大小时,不宜使用scale_pos_weight参数。

    使用官方数据例子:agaricus.txt.train 与 agaricus.txt.test

    系统Default,设置scale_pos_weight = 1。观察训练过程

    print("\n--------- scale_pos_weight = 1 -----------")
    dtrain = xgb.DMatrix('../demo_data/agaricus.txt.train')
    dtest = xgb.DMatrix('../demo_data/agaricus.txt.test')
    watchlist = [(dtrain, 'train'), (dtest, 'eval')]
    params = {'max_depth': 2, 'eta': 1, 'silent': 1, 'eval_metric': 'auc', "objective": "binary:logistic",
              "scale_pos_weight": 1}
    xgb.train(params=params, dtrain=dtrain, num_boost_round=5, evals=watchlist, verbose_eval=1)

    不平衡对比

    使用weight给样本赋予权重。

    label=1,权重设置为3

    label=0,  权重设置为1

    print("\n--------- custom set weight=3, scale_pos_weight=1-----------")
    dtrain = xgb.DMatrix('../demo_data/agaricus.txt.train', silent=True)
    dtest = xgb.DMatrix('../demo_data/agaricus.txt.test', silent=True)
    train_weight = [1 if i == 0 else 3 for i in dtrain.get_label().tolist()]
    test_weight = [1 if i == 0 else 3 for i in dtest.get_label().tolist()]
    dtrain2 = xgb.DMatrix('../demo_data/agaricus.txt.train', weight=train_weight, silent=True)
    dtest2 = xgb.DMatrix('../demo_data/agaricus.txt.test', weight=test_weight, silent=True)
    watchlist = [(dtrain2, 'train'), (dtest2, 'eval')]
    params = {'max_depth': 2, 'eta': 1, 'silent': 1, 'eval_metric': 'auc', "objective": "binary:logistic",
              "scale_pos_weight": 1}
    xgb.train(params=params, dtrain=dtrain2, num_boost_round=5, evals=watchlist, verbose_eval=1)

     将正样本复制成原来的3倍,和负样本拼起来组成训练集训练

    print("\n---------read agaricus.txt.xxx_weight3 scale_pos_weight = 1 -----------")
    dtrain = xgb.DMatrix('../demo_data/agaricus.txt.train_weight3')
    dtest = xgb.DMatrix('../demo_data/agaricus.txt.test_weight3')
    watchlist = [(dtrain, 'train'), (dtest, 'eval')]
    params = {'max_depth': 2, 'eta': 1, 'silent': 1, 'eval_metric': 'auc', "objective": "binary:logistic",
              "scale_pos_weight": 1}
    xgb.train(params=params, dtrain=dtrain, num_boost_round=5, evals=watchlist, verbose_eval=1)

    scale_pos_weight = 3

    print("\n--------- scale_pos_weight = 3-----------")
    dtrain = xgb.DMatrix('../demo_data/agaricus.txt.train', silent=True)
    dtest = xgb.DMatrix('../demo_data/agaricus.txt.test', silent=True)
    watchlist = [(dtrain, 'train'), (dtest, 'eval')]
    params = {'max_depth': 2, 'eta': 1, 'silent': 1, 'eval_metric': 'auc', "objective": "binary:logistic",
              "scale_pos_weight": 3}
    xgb.train(params=params, dtrain=dtrain, num_boost_round=5, evals=watchlist, verbose_eval=1)

    自定义损失函数,

    将正样本的logloss设置为负样本的3倍,然后求一阶导和二阶导.

    print("\n---------custom set weight=3, scale_pos_weight=1, use custom obj-----------")
    
    from sklearn.metrics import roc_auc_score
    
    ratio = 3
    
    def logistic_obj(p, dtrain):
        y = dtrain.get_label()
        grad = p * (ratio * y + 1 - y) - ratio * y
        hess = p * (1 - p) * (beta * y + 1 - y)
        return grad, hess
    
    
    def logistic_obj_feval(p, dtrain):
        y = dtrain.get_label()
        score = roc_auc_score(y, p)
        return 'feval-auc', score
    
    
    dtrain = xgb.DMatrix('../demo_data/agaricus.txt.train', silent=True)
    dtest = xgb.DMatrix('../demo_data/agaricus.txt.test', silent=True)
    train_weight = [1 if i == 0 else 3 for i in dtrain.get_label().tolist()]
    test_weight = [1 if i == 0 else 3 for i in dtest.get_label().tolist()]
    dtrain2 = xgb.DMatrix('../demo_data/agaricus.txt.train', weight=train_weight, silent=True)
    dtest2 = xgb.DMatrix('../demo_data/agaricus.txt.test', weight=test_weight, silent=True)
    watchlist = [(dtrain2, 'train'), (dtest2, 'eval')]
    params = {'max_depth': 2, 'eta': 1, 'silent': 1, 'eval_metric': 'auc', "objective": "binary:logistic",
              "scale_pos_weight": 1}
    xgb.train(params=params, dtrain=dtrain2, num_boost_round=5,
              evals=watchlist, verbose_eval=1, obj=logistic_obj, feval=logistic_obj_feval)

    5. 设置 subsample

    如果参数subsample < 1 ,此时将正样本复制成原来的3倍,训练结果还是会不一样,因为样本总数改变了,子采样就会不一样, 其他情况输出不会变。

    print("\n--------- scale_pos_weight = 3, subsample=0.8-----------")
    dtrain = xgb.DMatrix('../demo_data/agaricus.txt.train', silent=True)
    dtest = xgb.DMatrix('../demo_data/agaricus.txt.test', silent=True)
    watchlist = [(dtrain, 'train'), (dtest, 'eval')]
    params = {'max_depth': 2, 'eta': 1, 'silent': 1, 'eval_metric': 'auc', "objective": "binary:logistic",
              "scale_pos_weight": 3, "subsample":0.8}
    xgb.train(params=params, dtrain=dtrain, num_boost_round=5, evals=watchlist, verbose_eval=1)
    
    
    print("\n---------read agaricus.txt.xxx_weight3 scale_pos_weight = 1, subsample=0.8 -----------")
    dtrain = xgb.DMatrix('../demo_data/agaricus.txt.train_weight3')
    dtest = xgb.DMatrix('../demo_data/agaricus.txt.test_weight3')
    watchlist = [(dtrain, 'train'), (dtest, 'eval')]
    params = {'max_depth': 2, 'eta': 1, 'silent': 1, 'eval_metric': 'auc', "objective": "binary:logistic",
              "scale_pos_weight": 1, "subsample":0.8}
    xgb.train(params=params, dtrain=dtrain, num_boost_round=5, evals=watchlist, verbose_eval=1)

    三 结论

    sample_weight参数允许您为每个训练示例指定不同的权重。 scale_pos_weight参数允许您为整类示例(“正”类)提供权重。

    这些对应于成本敏感学习的两种不同方法。如果您认为错误分类正面示例(错过癌症患者)的成本对于所有正面示例都是相同的(但比错误分类负面示例的成本更高,例如告诉某人他们实际上没有癌症),那么您可以指定一个通过 scale_pos_weight 获得所有正面示例的权重.

    参考:

    样本不平衡问题操作手册 - 知乎


    不平衡处理:xgboost 中scale_pos_weight、给样本设置权重weight、 自定义损失函数 和 简单复制正样本的区别_大风车-CSDN博客

    展开全文
  • 目标检测 样本不平衡

    千次阅读 2020-04-09 16:47:32
    YOLO和SSD可以算one-stage算法里的佼佼者,加上R-CNN系列算法,这几种算法可以说是目标检测领域非常经典的算法了。这几种算法在提出之后经过数次改进,都得到了很高的精确度,...正负样本比例极度不平衡。由于one-s...
  • 样本不平衡问题分析与部分解决办法

    万次阅读 多人点赞 2019-01-20 14:11:03
    最近工作中在处理文本分类问题遇到了分类均衡的问题,主要还是样本太少还同时非常的均衡正负样本1:10(类别不平衡比例超过4:1,就会造成偏移),就使用了SMOTE方法。 注意:在进行数据增广的时候一定要将测试集...
  • 样本不平衡问题

    千次阅读 2019-04-10 09:35:50
    样本不平衡是指:不同类别的样本差别比较大,比如说正类和负类的样本比例为50:1。 处理样本不平衡的原因: 一般而已,如果类别不平衡比例超过4:1,那么其分类器会大大地因为数据不平衡性而无法满足分类要求的。...
  • 睡眠数据中各个阶段的样本数差异较大,睡眠数据的自动分期是一个典型的样本不平衡的机器学习问题。均衡样本方法通过抽样的手段来平衡样本,是解决样本不平衡问题的主要方法。采用均衡样本方法来平衡睡眠数据的不同...
  • 利用采样方法解决数据样本不平衡问题的原理与示例
  • train,X_test,y_train,y_test = model_selection.train_test_split(X,y,test_size = 0.3, random_state = 1234)# 导入第三方包from imblearn.over_sampling import SMOTE# 运用SMOTE算法实现训练数据集的平衡over_...
  • 在基于内容的图像检索中,支持向量机(SVM)的分类性能不仅受到样本不平衡的影响,而且由于图像的视觉多样性,导致在分类超平面附近找到正例样本,无法提高分类器性能。针对上述问题,提出一种二阶段的SVM 超平面...
  • 机器学习中样本不平衡的解决方案

    千次阅读 2021-11-26 14:17:55
    文章目录采样正样本过采样正样本smote负样本欠采样基于聚类的随机采样(CBO)SMOTEBoost(采样方法和集成学习的集成)将二分类看成一分类或异常检测问题focal lossimbalance-XGBoost正负...这种做法建议。 2.可以通
  • 文章目录focal loss 提出的场景和针对的问题focal loss 提出的场景:目标检测focal loss 针对的问题:类别不平衡如何处理目标检测下的类别不平衡如何理解目标检测场景下的样本和类别two-stageone-stagefocal loss的...
  • 样本不平衡的常用处理方法

    千次阅读 2020-04-20 15:39:28
    文章目录数据不平衡为什么类别不平横会影响模型的输出?如何解决 数据不平衡 很多算法都有一个基本假设,那就是数据分布是均匀的。当我们把这些算法直接应用于实际数据时,大多数情况下都无法取得理想的结果。因为...
  • 处理样本不平衡LOSS—Focal Loss

    千次阅读 2020-01-06 16:32:46
    Focal Loss是为了处理样本不平衡问题而提出的,经时间验证,在多种任务上,效果还是不错的。在理解Focal Loss前,需要先深刻理一下交叉熵损失,和带权重的交叉熵损失。然后我们从样本权重的角度出发,理解Focal Loss...
  • 一般one stage目标检测模型存在正负样本数量均衡问题,基于此Focal Loss for Dense Object Detection一文提出Focal loss计算方法用于解决样本不平衡问题。
  • 1.如何解决机器学习中数据不平衡问题 2.Learning from imbalanced data 原文 3.对于正负样本不均衡的解决方法 4.2中论文的翻译总结 一、 问题背分析 1.背景 在学术研究与教学中,很多算法都有一个基本假设,那就是...
  • 现实情况中,很多机器学习训练...文章目录1 样本不平衡的解决思路1.2 将不平衡样本当作离群点1.2 欠采样/过采样1.3 训练策略的优化1.3.1 Focal_Loss1.3.2 class_weight1.4 不平衡评价指标:不要ROC,用Precision/R...
  • 1、正负样本不平衡问题如何解决?

    千次阅读 2021-07-08 14:02:01
    1、过采样、欠采样的方式对不平衡的正负样本进行采样。 2、正负样本各自在进行训练时,设置不用的惩罚系数。 2、集成的方式:例如,在数据集中的正、负样本分别为100和10000,比例为1:100。此时可以将负样本(类别...
  • 炼丹笔记一:样本不平衡问题

    千次阅读 2019-01-29 00:07:08
    欢迎大家关注微信公众号:baihuaML,白话机器学习。 码字不易,未经授权禁止转载,如转载,请...你好,能能谈一谈在深度学习中,怎样解决样本不平衡问题 ? 1. 什么是样本不平衡问题? 所谓的类别不平衡问题指的...
  • 什么是样本不平衡? 在计算机视觉(CV)任务里常常会碰到类别不平衡的问题, 例如: 图片分类任务:有的类别图片多,有的类别图片少 检测任务:现在的检测方法如SSD和RCNN系列,都使用anchor机制。 训练时正负...
  • 样本不平衡问题解决方法总结

    千次阅读 2019-06-25 11:55:00
    样本不平衡问题:数据集中,每个类别下的样本数目相差很大。以下以二分类问题为例进行讨论: 图示:坏样本占比:0.17%( 492(坏样本) : 284315(好样本)) 理想的样本应该是50:50,但...
  • 解决不平衡问题? 类别不平衡(class-imbalance)就是指分类任务中不同类别的训练样例数目差别很大的情况。在现实的分类学习任务中,我们经常会遇到类别不平衡,例如在通过拆分法解决多分类问题时,即使原始问题中...
  • 逻辑回归中样本不平衡的解决方案

    千次阅读 2020-11-10 11:19:33
    逻辑回归中样本不平衡的解决方案: 前情提要:在逻辑回归中,如果数据不平衡会导致如下情况,分类效果差: 改进:对不同类型进行加权,公式如下: l(θ∣Y)=⟨∏i=1nLg−1(ηi∣θ)⟩WL⟨∏j=1nNL[1−g−1(ηj∣θ...
  • 分类模型中各种类型的权重,可以输入,即考虑权重,或者说所有类型的权重一样。 手动输入各个类型的权重: 比如对于0,1的二元模型,定义class_weight={0:0.8, 1:0.2},即表示类型0的权重为80%,而类型1的权重为...
  • 样本不平衡处理

    千次阅读 2019-05-27 17:28:15
    采样最邻近算法,计算出每个少数类样本的K个近邻; 从K个近邻中随机挑选N个样本进行随机线性插值; 构造新的少数类样本; 将新样本与原数据合成,产生新的训练集; 代码实现: from imblearn.over_...
  • 深度学习样本不平衡通用处理方法

    千次阅读 2019-02-18 19:54:17
    在一个分类问题中,如果在所有你想要预测的类别里有一个或者多个类别的样本量非常少,那你的数据也许就面临不平衡类别的问题。 举例 1.欺诈预测(欺诈的数量远远小于真实交易的数量) 2.自然灾害预测(不好的事情远...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 55,117
精华内容 22,046
关键字:

样本不平衡

友情链接: e.zip