机器学习中样本不平衡的解决方案

注:本文中,将大众样本视为负样本,小众样本视为正样本。即正样本很少,负样本很多。

采样

首先最基本的就是采样,分为过采样和欠采样。

正样本过采样

  • 1.如果随机的复制多分正样本进行过采样,那么必然会导致过拟合,因为训练数据中的正样本会反复出现。这种做法不建议。
  • 2.可以通过smote的方式对正样本进行过采样。

正样本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. 通过计算n维空间的欧氏距离,得到距离 x i x_i xi最近的K个 S m i n S_{min} Smin中的样本数据;
  3. 然后从K个近邻中,随机选择一个样本,产生人工合成的数据

x n e w = x i + ( x ^ i − x i ) ∗ δ , 其 中 S m i n 是 少 数 类 样 本 , x ^ i 是 x i 的 其 中 一 个 近 邻 , δ ∈ [ 0 , 1 ] 是 一 个 随 机 数 。 x_{new} = x_i + (\hat x_i - x_i) * δ,\\ 其中S_{min}是少数类样本,\\ \hat x_i是x_i的其中一个近邻,\\ δ∈[0, 1]是一个随机数。 xnew=xi+(x^ixi)δSminx^ixiδ[0,1]

在这里插入图片描述
上图展示了SMOTE的具体过程,
(a)图展示了一个典型的不平衡的数据,SMOTE中的 K 取值为6。
(b)图中展示了一个随机产生的合成样本,这个样本是沿着 x i x_{i} xi x i ^ \hat{x_{i}} xi^的直线产生的。

SMOTE方法是一种过采样的方法,它克服了过采样的一些缺点,而且加强了原始数据。

但是SMOTE方法可能会造成一定的过拟合。

除了常用的smote之外,还有自适应合成采样,比如Borderline-SMOTE、Adaptive Synthetic Sampling(ADA-SYN),请参考:https://blog.csdn.net/hren_ron/article/details/81172044

负样本欠采样

  • 在负样本空间中,随机的丢掉一些样本。

因为下采样会丢失信息,如何减少信息的损失呢?

  1. 第一种方法叫做EasyEnsemble,利用模型融合的方法(Ensemble):多次下采样(放回采样,这样产生的训练集才相互独立)产生多个不同的训练集,进而训练多个不同的分类器,通过组合多个分类器的结果得到最终的结果。

  2. 第二种方法叫做BalanceCascade,利用增量训练的思想(Boosting):先通过一次下采样产生训练集,训练一个分类器,对于那些分类正确的大众样本不放回,然后对这个更小的大众样本下采样产生训练集,训练第二个分类器,以此类推,最终组合所有分类器的结果得到最终结果。

    https://zhuanlan.zhihu.com/p/36093594

  3. 第三种方法是利用KNN试图挑选那些最具代表性的大众样本,叫做NearMiss,这类方法计算量很大,感兴趣的可以参考“Learning from Imbalanced Data”这篇综述的3.2.1节。

基于聚类的随机采样(CBO)

基于聚类的随机采样方法可以用来解决类内不平衡问题,主要利用的聚类的方法。具体的过程如下:

  • 随机选择K个样本作为K个簇,并且计算K类样本在特征空间的平均值,作为聚类中心;
  • 对于剩下的每一个样本,计算它和K个聚类中心的欧氏距离,根据欧式聚类将其分配到最近的类簇中;
  • 更新每个簇的聚类中心,直到所有的样本都用完;

在这里插入图片描述
(a)中展示了原始数据集,多数类中3个类簇( m m a j = 3 m_{maj} = 3 mmaj=3),每个类簇中的样本数分别是:20、10、8。而少数类中有2个类簇(m_{min} 2),每个类簇中的样本数是:8, 5。
(b)中展示了5个类簇中,各自有三个样本,并且已经计算好各自的聚类中心。同时还存在另外五个未分类的样本。
(c)展示了如果对5个未分类的样本进行分类,每一个类簇的聚类中心发生改变。一旦所有的样本都用完,那么CBO使用过采样的方法填充所有的多数类的类簇。因此,多数类的类簇中的样本个数相同。
(d)中是使用CBO之后的样本分布情况,因此,类簇B和C的样本数都是20。使用 N C B O N_{CBO} NCBO表示多数类的样本数量,因此, N C B O = N m a j + E m a j , N C B O = 60 N_{CBO} = N_{maj} + E_{maj},N_{CBO}=60 NCBO=Nmaj+EmajNCBO=60。然后我们使用过采样的方法填充少数类的类簇,使得每一类簇中包含 N C B O / m m i n N_{CBO}/m_{min} NCBO/mmin个样本。因此,这个例子中少数类的每一类簇应该包含 60 / 2 60/2 60/2个样本。

从上述例子中,我们可以发现CBO对于每一个类簇都会产生足够多的样本,因此,对于不同的类它具有很强的表示能力。同时,在CBO的过程中,我们也可以采用其他的采样方法,比如smote。

SMOTEBoost(采样方法和集成学习的集成)

SMOTEBoost主要是把SMOTE和AdaBoost.M2集成在一起,SMOTEBoost方法在每次Boost迭代过程中使用合成数据的方法。因此,每一次迭代过程中的分类器都会集中到更多的少数类样本。

代码参考:

https://github.com/aniketdwivedi12/SMOTEBoost/blob/master/SMOTEBoost.ipynb

将二分类看成一分类或异常检测问题

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

说明:对于正负样本极不均匀的问题,使用异常检测,或者一分类问题,也是一个思路。

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

focal loss

自定义损失函数:focal loss

关于focal loss参考:https://blog.csdn.net/qq_42363032/article/details/121540392

imbalance-XGBoost

pip install imxgboost

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)

官网如下:
https://github.com/jhwjhw0123/Imbalance-XGBoost

正负样本失衡时的评估指标

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









参考链接:

https://blog.csdn.net/jemila/article/details/77992967

https://blog.csdn.net/hren_ron/article/details/81172044

https://www.zhihu.com/question/428547855

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WGS.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值