全部文章

不均衡数据问题&欠采样、过采样

类别不平衡数据集基本介绍

其实,在现实环境中,采集的数据(建模样本)往往是⽐例失衡的。⽐如⽹贷数据,逾期⼈数的⽐例是极低的(千分之⼏的⽐例);奢侈品消费⼈群鉴定等。

创造数据不均衡数据集

sklearn.datasets.make_classification() 是 scikit-learn 中用于​​生成人工分类数据集​​的核心函数

参数详解表

参数 默认值 说明 影响数据特性
n_samples 100 总样本数 数据集规模
n_features 20 特征总数 维度复杂性
n_informative 2 有效特征数 实际预测能力
n_redundant 2 冗余特征数(由有效特征线性组合) 特征间相关性
n_repeated 0 复制特征数:重复特征数(随机复制) 无信息特征
n_classes 2 类别数量 分类复杂度
weights None 类别比例 平衡性调整
flip_y 0.01 标签噪声 分类难度
class_sep 1.0 类别分离度 区分难度(>1易分,<1难分)
n_clusters_per_class 2 每类簇数 类别内部结构
hypercube True 簇形状  
random_state None 随机种子  

生成3类不均衡数据:

from sklearn.datasets import make_classification
from collections import Counter
import matplotlib.pyplot as plt
#生成不均衡数据
X,y=make_classification(n_samples=5000,n_features=2,n_informative=2,n_redundant=0,n_repeated=0,n_classes=3,weights=[0.01,0.05,0.94],
                       n_clusters_per_class=1,random_state=42)
#统计各个标签的样本数量
print(Counter(y))#Counter({2: 4668, 1: 266, 0: 66})
#数据可视化
plt.figure(figsize=(20,8))
plt.scatter(X[:,0],X[:,1],c=y)
plt.show()

 

可以看出样本的三个标签中,1,2的样本量极少,样本失衡。接下来,我们就要基于以上数据,进⾏相应的处理。

不均衡数据处理方式

在Python中,有Imblearn包,它就是为处理数据⽐例失衡⽽⽣的。官网: https://imbalanced-learn.org/stable/

下⾯使⽤imblearn进⾏不均衡数据处理。

安装Imblearn包

pip install imbalanced-learn

第三⽅包链接:https://pypi.org/project/imbalanced-learn/

关于类别不平衡的问题,主要有两种处理⽅式:

  • 过采样
    • 增加数量较少那⼀类样本的数量,使得正负样本⽐例均衡。
  • ⽋采样
    • 减少数量较多那⼀类样本的数量,使得正负样本⽐例均衡。

过采样

什么是过采样⽅法

对训练集⾥的少数类进⾏“过采样”(oversampling),即增加⼀些少数类样本使得正、反例数⽬接近,然后再进⾏学 习。

随机过采样⽅法

随机过采样是在少数类Smin 中随机选择⼀些样本,然后通过复制所选择的样本⽣成样本集E,将它们添加到Smin  中来扩⼤原始数据集,从⽽得到新的少数类集合Snew_min。

新的数据集Snew_min=Smin+E

通过代码实现随机过采样⽅法:

from imblearn.over_sampling import RandomOverSampler
# 随机过采样
RandomOverSampler_X,RandomOverSampler_y=RandomOverSampler(random_state=42).fit_resample(X,y)
# 查看新数据分布情况
Counter(RandomOverSampler_y)#Counter({2: 4668, 1: 4668, 0: 4668})
plt.figure(dpi=100)
plt.scatter(RandomOverSampler_X[:,0],RandomOverSampler_X[:,1],c=RandomOverSampler_y)
plt.show()

 

缺点:
对于随机过采样,由于需要对少数类样本进⾏复制来扩⼤数据集,造成模型训练复杂度加⼤。
另⼀⽅⾯也容易造成模型的过拟合问题,因为随机过采样是简单的对初始样本进⾏复制采样,这就使得学习器学得的规则过于具体化,不利于学习器的泛化性能,造成过拟合问题。
为了解决随机过采样中造成模型过拟合问题,⼜能保证实现数据集均衡的⽬的,出现了过采样法代表性的算法SMOTE算法。

过采样代表性算法-SMOTE

SMOTE全称是Synthetic Minority Oversampling即合成少数类过采样技术。
SMOTE算法是对随机过采样⽅法的⼀个改进算法,由于随机过采样⽅法是直接对少数类进⾏重采⽤,会使训练集中有很多重复的样本,容易造成产⽣的模型过拟合问题。⽽SMOTE算法的基本思想:是对每个少数类样本Xi,从它的最近邻中随机选择一个样本;(是少数类中的一个样本),然后在Xi之间的连线上随机选择一点作为新合成的少数类样本。

SMOTE算法合成新少数类样本的算法描述如下:
1)对于少数类中的每一个样本Xi,以欧氏距离为标准计算它到少数类样本集Smin 中所有样本的距离,得到其k近邻。
2)根据样本不平衡比例设置一个采样比例以确定采样倍率N,对于每一个少数类样本Xi,从其k近邻中随机选择若干个样本,假设选择的是

 3)对于每一个随机选出来的近邻 ,分别与Xi按照如下公式构建新的样本。

 

 

我们⽤图⽂表达的⽅式,再来描述⼀下SMOTE算法。
1) 先随机选定⼀个少数类样本Xi

2) 找出这个少数类样本Xi的K个近邻(假设K=5),5个近邻已经被圈出。

 

3) 随机从这K个近邻中选出⼀个样本(⽤绿⾊圈出来了)。

4)在少数类样本Xi和被选中的这个近邻样本之间的连线上,随机找⼀点。这个点就是⼈⼯合成的新的样本点(绿⾊正号标出)。 

SMOTE算法摒弃了随机过采样复制样本的做法,可以防⽌随机过采样中容易过拟合的问题,实践证明此⽅法可以提⾼分类器的性能。
代码实现:
from imblearn.over_sampling import SMOTE
# SMOTE过采样
SMOTE_X,SMOTE_y=SMOTE(random_state=42).fit_resample(X,y)
# 查看新数据分布情况
Counter(SMOTE_y)
# 采样后样本结果
#Counter({2: 4668, 1: 4668, 0: 4668})
plt.figure(dpi=100)
plt.scatter(SMOTE_X[:,0],SMOTE_X[:,1],c=SMOTE_y)
plt.show()

欠采样

什么是欠采样⽅法

直接对训练集中多数类样本进⾏“⽋采样”(undersampling),即去除⼀些多数类中的样本使得正例、反例数⽬接近,然后再进行学习。

随机欠采样⽅法

随机⽋采样顾名思义即从多数类Smax中随机选择⼀些样样本组成样本集E。然后将样本集E从Smax中移除。

新的数据集:

API

imblearn.under_sampling.RandomUnderSampler(),这是imbalanced-learn库(imblearn)中用于处理不平衡数据集的一种下采样方法。

它的工作原理:从多数类中随机删除一些样本,使得多数类和少数类的样本数量达到平衡(通常是1:1,但也可以通过参数调整)。

使用场景

  • 当少数类样本数量不足时
  • 当计算资源有限(欠采样减少数据量)
  • 当多数类样本可被合理精简时
  • 常用于二分类问题中类分布失衡的情况

工作流程示例

假设原始数据集:

  • 多数类:10,000个样本(类别0)
  • 少数类:200个样本(类别1)

应用 RandomUnderSampler 后:

  • 保留所有200个少数类样本
  • 随机选择200个多数类样本
  • 最终平衡数据集:400个样本(200+200)

代码实现

from imblearn.under_sampling import RandomUnderSampler
# 随机欠采样采样
RandomUnderSampler_X,RandomUnderSampler_y=RandomUnderSampler(random_state=42).fit_resample(X,y)
# 查看新数据分布情况
Counter(RandomUnderSampler_y)
# 采样后样本结果
#Counter({0: 66, 1: 66, 2: 66})
plt.figure(dpi=100)
plt.scatter(RandomUnderSampler_X[:,0],RandomUnderSampler_X[:,1],c=RandomUnderSampler_y)
plt.show() 

优缺点分析

✅ 优点:

  1. ​高效减少数据规模​​(提高计算效率)
  2. ​防止模型偏置​​(避免模型忽略少数类)
  3. ​简单易实现​
  4. 适合大规模数据集

❌ 缺点:

  1. ​信息丢失​​(可能删除重要样本)
    将多数类样本删除有可能会导致分类器丢失有关多数类的重要信息
  2. ​降低模型泛化能力​
  3. 对稀有事件敏感(可能删除关键样本)
  4. 可能放大噪声影响
类权重替代方案​​:
# 在不采样时调整类权重
model = RandomForestClassifier(class_weight='balanced')

典型应用场景

  1. 金融欺诈检测(欺诈交易极少)
  2. 疾病诊断(罕见病例较少)
  3. 设备故障预测(故障事件稀少)
  4. 网络入侵检测(攻击行为少见)

📌 ​​重要提示​​:欠采样最适合多数类样本高度冗余的情况。对于高价值多数类样本,应考虑使用过采样(SMOTE)或组合方法。

官网

深入学习Imbalanced-learn处理不均衡数据,请参照官网: https://imbalanced-learn.org/stable/

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2025-06-03 11:49  指尖下的世界  阅读(80)  评论(0)    收藏  举报