imblearn库实现过采样和欠采样

#生成数据集  
from sklearn.datasets import make_classification
X, y = make_classification(n_samples=5000, n_features=2,
                                n_informative=2, n_redundant=0, 
                                n_repeated=0, n_classes=3, 
                                n_clusters_per_class=1, 
                                weights=[0.01, 0.05, 0.94], 
                                class_sep=0.8, random_state=0)
#随机过采样  
from imblearn.over_sampling import RandomOverSampler, BorderlineSMOTE

X_resampled, y_resampled = RandomOverSampler().fit_resample(X, y)  
#SMOTE过采样及其变体  
from imblearn.over_sampling import SMOTE  
X_resampled_smote, y_resampled_smote = SMOTE().fit_resample(X, y)  
X_resampled, y_resampled = BorderlineSMOTE(kind='borderline-1').fit_resample(X, y)
X_resampled, y_resampled = BorderlineSMOTE(kind='borderline-2').fit_resample(X, y)
#ADASYN过采样  
from imblearn.over_sampling import ADASYN  
X_resampled_adasyn, y_resampled_adasyn = ADASYN().fit_resample(X, y)  
#随机欠采样  
from imblearn.under_sampling import RandomUnderSampler  
X_resampled, y_resampled = RandomUnderSampler().fit_resample(X, y)  
#基于k-means聚类的欠采样  
from imblearn.under_sampling import ClusterCentroids  
X_resampled, y_resampled = ClusterCentroids().fit_resample(X, y)  
#基于最近邻算法的欠采样  
from imblearn.under_sampling import RepeatedEditedNearestNeighbours  
X_resampled, y_resampled = RepeatedEditedNearestNeighbours().fit_resample(X, y)
#在数据上运用一种分类器
#然后将概率低于阈值的样本剔除掉
#从而实现欠采样  
from sklearn.linear_model import LogisticRegression  
from imblearn.under_sampling import InstanceHardnessThreshold  
lr_underS = InstanceHardnessThreshold(
               random_state=0, estimator=LogisticRegression())
X_resampled, y_resampled = lr_underS.fit_resample(X, y) 

代码示例演示了如何使用 scikit-learnimblearnimbalanced-learn)库来处理多类不平衡问题。代码中展示了常见的几种过采样和欠采样方法,以及它们在数据集上的应用。下面对每个方法的含义和用法做一个简要的说明,帮助理解这些代码的作用。


1. 数据集的生成

from sklearn.datasets import make_classification

X, y = make_classification(n_samples=5000, 
                           n_features=2,
                           n_informative=2, 
                           n_redundant=0, 
                           n_repeated=0, 
                           n_classes=3, 
                           n_clusters_per_class=1, 
                           weights=[0.01, 0.05, 0.94], 
                           class_sep=0.8, 
                           random_state=0)
  • n_samples=5000:生成 5000 条样本。
  • n_features=2:有 2 个特征。
  • n_informative=2, n_redundant=0, n_repeated=0:2 个有用特征,没有冗余特征和重复特征。
  • n_classes=3:目标变量有 3 个类别。
  • n_clusters_per_class=1:每个类别只有 1 个簇。
  • weights=[0.01, 0.05, 0.94]:三个类别的分布分别为 1%、5% 和 94%,这就使得数据集高度不平衡。
  • class_sep=0.8:类间分离度,用于控制数据分布的可分离程度。
  • random_state=0:保证可重复性。

这段代码会返回特征矩阵 X 和标签 y。由于 weights 的设定,得到的数据集中第三个类别占绝大多数,而前两个类别是少数类。


2. 随机过采样(RandomOverSampler)

from imblearn.over_sampling import RandomOverSampler

X_resampled, y_resampled = RandomOverSampler().fit_resample(X, y)
  • RandomOverSampler 会对少数类进行随机复制(简单地复制少数类样本)直到满足指定的采样策略(通常是让少数类样本数量与多数类相当)。
  • 优点:实现简单,速度快。
  • 缺点:容易导致过拟合,因为它只是无选择地重复少数类样本。

3. SMOTE 过采样

from imblearn.over_sampling import SMOTE

X_resampled_smote, y_resampled_smote = SMOTE().fit_resample(X, y)
  • SMOTE (Synthetic Minority Over-sampling Technique) 会在少数类样本之间进行插值,合成新的“虚拟”少数类样本,从而平衡各类样本数量。
  • 优点:在样本空间中产生新的少数类样本,避免了简单过采样的“机械复制”问题,能够降低过拟合的风险。
  • 缺点:SMOTE 会在特征空间中对少数类做线性插值,对于非线性、复杂的分类边界可能仍然难以处理。

4. Borderline-SMOTE 过采样

from imblearn.over_sampling import BorderlineSMOTE

X_resampled, y_resampled = BorderlineSMOTE(kind='borderline-1').fit_resample(X, y)
X_resampled, y_resampled = BorderlineSMOTE(kind='borderline-2').fit_resample(X, y)
  • Borderline-SMOTE 是对 SMOTE 的改进版,通过只在“边界样本”周围进行插值来合成新的少数类样本。
  • kind=‘borderline-1’ / ‘borderline-2’:这是两个不同的边界合成策略:
    • borderline-1:更侧重在少数类和多数类接壤的“危险边界”区域来合成新样本。
    • borderline-2:同样着重于边界区域,但在合成策略上更激进,合成样本可能离多数类更近。
  • 相比原始 SMOTE,更能强化“边界区域”的少数类特征,从而改善分类器在边界上的识别能力。

注意:在新版本的 imbalanced-learn 中,kind 参数有时会更名为 borderline_kind,或者参数名称已被弃用。若出现报错,可参考对应版本的官方文档或更改参数名称。


5. ADASYN 过采样

from imblearn.over_sampling import ADASYN

X_resampled_adasyn, y_resampled_adasyn = ADASYN().fit_resample(X, y)
  • ADASYN(Adaptive Synthetic Sampling) 类似于 SMOTE,都是通过插值来生成新的少数类样本,但它会根据样本分布自适应地为“难以学习”的区域生成更多合成样本,帮助分类器更好地学习难区分的边界。
  • 优点:更关注困难样本所在的区域,理论上能进一步提升分类效果。
  • 缺点:与 SMOTE 相似,插值合成的样本只在已有的少数类分布周围生成,对极端复杂分布仍会存在局限性。

6. 随机欠采样(RandomUnderSampler)

from imblearn.under_sampling import RandomUnderSampler

X_resampled, y_resampled = RandomUnderSampler().fit_resample(X, y)
  • RandomUnderSampler 会随机删除多数类样本,直到达到指定比例,使得少数类与多数类平衡。
  • 优点:实现简单,速度快,可以显著减少训练数据量,从而降低训练时间。
  • 缺点:直接丢弃了大量的多数类样本,可能会丢失有用的信息,导致分类器性能下降。

7. 基于 K-means 聚类的欠采样(ClusterCentroids)

from imblearn.under_sampling import ClusterCentroids

X_resampled, y_resampled = ClusterCentroids().fit_resample(X, y)
  • ClusterCentroids 会使用聚类算法(默认 KMeans)将多数类样本聚为若干簇,然后用各簇的“质心”(平均值)来代表这个簇,从而减少多数类样本数量。
  • 优点:相比随机欠采样,能够保留更多的多数类“代表性”信息。
  • 缺点:在聚类过程中,如果聚类效果不好,依旧可能丢失关键信息。

8. 基于最近邻算法的欠采样(RepeatedEditedNearestNeighbours)

from imblearn.under_sampling import RepeatedEditedNearestNeighbours

X_resampled, y_resampled = RepeatedEditedNearestNeighbours().fit_resample(X, y)
  • Edited Nearest Neighbours (ENN) 的原理是:对于多数类中的某些“噪声”或“不典型”样本,如果它在一定数量的最近邻中属于少数类占多数,则认为它是可疑样本,将其剔除。
  • RepeatedEditedNearestNeighbours 会将 ENN 的过程重复多次,使得数据集在多数类区域中“清洗”得更干净。
  • 优点:逐步“编辑”出一个更纯净、更有代表性的多数类数据子集。
  • 缺点:需要进行多轮迭代,执行速度会比随机欠采样慢一些。

9. 基于分类器预测概率的欠采样(InstanceHardnessThreshold)

from sklearn.linear_model import LogisticRegression
from imblearn.under_sampling import InstanceHardnessThreshold

lr_underS = InstanceHardnessThreshold(
               random_state=0, 
               estimator=LogisticRegression()
            )
X_resampled, y_resampled = lr_underS.fit_resample(X, y)
  • InstanceHardnessThreshold:先训练一个指定的分类器(这里是 LogisticRegression),计算每个样本被预测为所属类别的概率,并对概率低于阈值(即分类器很难正确识别的样本)进行剔除。
  • 这种方法相当于用已有模型预测“难样本”(hard instance),若一个多数类样本被模型认为“存在较高错分风险”,则将它剔除掉,减少其对模型训练的干扰。
  • 优点:保留对分类器来说“容易”或“典型”的多数类样本,丢弃难样本,提高模型对少数类的学习能力。
  • 缺点:需要先训练一个初步模型,对模型的依赖较大,如果模型本身偏差较大,也可能错删有价值的多数类样本。

总结

不平衡数据集 的场景下,通常需要结合以下几方面来进行全面的评估和选择:

  1. 过采样 vs 欠采样
    • 过采样会增加训练集大小,可能提高对少数类的学习能力,但也可能导致过拟合或数据冗余。
    • 欠采样则会减少数据量、加快训练速度,但可能丢失信息。
  2. 不同的过采样方法(RandomOverSampler、SMOTE、Borderline-SMOTE、ADASYN 等)和 欠采样方法(RandomUnderSampler、ClusterCentroids、ENN 系列、IHT 等)对数据的“处理方式”不同,需要根据实际数据分布、模型需求和性能指标来做选择。
  3. 模型评估指标:对于不平衡场景,需要更多关注 AUC / ROC、Precision / Recall、F1-score 等指标,而不仅仅是准确率(Accuracy)。
  4. 实际业务场景:在金融风控或评分卡建模中,对不同类型错误(例如,错杀还是误放)会有不同的风险成本,需要在业务需求和模型表现之间做权衡。

可以多做实验,比较不同采样方法对模型指标(如 AUC、F1-score、KS 等)的影响,最终选出最适合业务目标和数据特点的方法。

### 随机欠采样随机过采样 #### 定义与原理 在处理数据集类别不平衡问题时,两种常见的策略是随机欠采样随机过采样。 - **随机欠采样**是指减少多数类样本的数量来平衡不同类别的比例。通过这种方式可以使得模型训练过程中各类别之间的数量差异减小,从而提高少数类识别率[^1]。 - **随机过采样**则是指增加少数类样本的数量以达到同样的目的。这通常通过对现有少数类实例进行复制或合成新实例完成[^2]。 #### 实现方式 ##### Python 中的实现 对于Python编程环境而言: - 使用`imbalanced-learn`能够方便地执行这两种操作。以下是具体代码示例展示如何利用该来进行随机欠采样以及查看重采样后的类别分布情况: ```python from imblearn.under_sampling import RandomUnderSampler import pandas as pd rus = RandomUnderSampler(random_state=42) X_resampled, y_resampled = rus.fit_resample(X, y) class_counts_resampled = pd.Series(y_resampled).value_counts(normalize=True) print("Resampled Class Proportions:", class_counts_resampled) ``` 而针对随机过采样,则可以通过如下方式进行: ```python from imblearn.over_sampling import RandomOverSampler ros = RandomOverSampler(random_state=42) X_ros, y_ros = ros.fit_resample(X, y) class_counts_ros = pd.Series(y_ros).value_counts(normalize=True) print("ROS Resampled Class Proportions:", class_counts_ros) ``` #### 应用场景 当面对高度偏斜的数据集时,选择哪种方法取决于具体情况: - 如果去除部分多数类不会丢失重要信息,并且计算资源有限的情况下,可以选择随机欠采样; - 当希望保留所有原始观测值并增强对稀有事件的学习能力时,应该考虑采用随机过采样或其他更复杂的增广技术如SMOTE(Synthetic Minority Over-sampling Technique),它可以在特征空间内创建新的虚拟成员而不是简单重复已有记录。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

彬彬侠

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

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

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

打赏作者

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

抵扣说明:

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

余额充值