数据不均衡处理一:数据重采样

数据不均衡是指在数据集中不同类别的样本数量差异较大,这可能会导致模型在训练和预测过程中对少数类样本的识别能力不足。数据重采样是一种常用的处理方法,可以通过增加少数类样本或减少多数类样本来平衡数据集,从而提高模型的性能。

常用的数据重采样方法有:过采样,欠采样和混合采样三种

目录

一:过采样(Oversampling)

二、欠采样(Undersampling)

三、混合采样(Synthetic Sampling)

一:过采样(Oversampling)

通过复制少数类样本来增加其数量,使得少数类样本与多数类样本数量相近。常见的过采样方法包括随机过采样、SMOTE(Synthetic Minority Over-sampling Technique)和 ADASYN(Adaptive Synthetic Sampling)等。

# 使用sklearn.datasets库生成不均衡数据集
from sklearn.datasets import make_classification
from collections import Counter
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)
print('Origin',Counter(y))
from imblearn.over_sampling import RandomOverSampler,SMOTE, ADASYN
'''
   RandomOverSampler:随机采样少数类的样本, 使得每类样本的比例为1:1:1
   SMOTE:对于少数类样本a, 随机选择一个最近邻的样本b, 然后从a与b的连线上随机选取一个点c作为新的少数类样本
   ADASYN: 关注的是在那些基于K最近邻分类器被错误分类的原始样本附近生成新的少数类样本,注意数据比例
'''
ros = RandomOverSampler(random_state=0)
X_resampled, y_resampled = ros.fit_resample(X, y)
print('RandomOverSampler',sorted(Counter(y_resampled).items()))

X_resampled_smote, y_resampled_smote = SMOTE().fit_resample(X, y)
print('SMOTE',sorted(Counter(y_resampled_smote).items()))
'''SMOTE变形
   from imblearn.over_sampling import BorderlineSMOTE
   BorderlineSMOTE(kind='borderline-1').fit_sample(X, y)
    kind = 'borderline-1' # 最近邻中的随机样本b与该少数类样本a来自于不同的类
           'borderline-2' # 随机样本b可以是属于任何一个类的样本
'''

X_resampled_adasyn, y_resampled_adasyn = ADASYN().fit_resample(X, y)
print('ADASYN',sorted(Counter(y_resampled_adasyn).items()))
二、欠采样(Undersampling)

通过删除多数类样本来减少其数量,使得多数类样本与少数类样本数量相近。欠采样方法包括随机欠采样、NearMiss等。

'''
   RandomUnderSampler: 就是从多数类样本中随机选取一些剔除掉,容易剔除重要信息。replacement=True参数, 可以实现自助法(boostrap)抽样.使用默认参数的时候, 采用的是不重复采样;
   EasyEnsemble:基于无监督的方式从多数类样本中生成子集进行欠采样.
                n_subsets控制的是子集的个数, replacement 决定是有放回还是无放回的随机采样。
   BalanceCascade:采用了有监督结合Boosting的方式,Boosting特点则体现在每一轮丢弃被正确分类的样本,进而后续基学习器会更注重那些之前分类错误的样本
   ClusterCentroids:减少数据集的样本数量, 剩下的样本是由原始数据集生成的, 而不是直接来源于原始数据集。
   NearMiss: version=1,选择到最近的K个少数类样本平均距离最近的多数类样本;
             version=2,选择到最远的K个少数类样本平均距离最近的多数类样本;
             version=3,对于每个少数类样本选择K个最近的多数类样本,目的是保证每个少数类样本都被多数类样本包围
   EditedNearestNeighbours:应用最近邻算法来编辑(edit)数据集, 找出那些与邻居不太友好的样本然后移除.
   Tomek Links:寻找的是噪声点或者边界点,这些点是不同类别之间距离比较近的样本对.只适用于2分类
'''
from imblearn.under_sampling import RandomUnderSampler, ClusterCentroids, NearMiss, EditedNearestNeighbours, TomekLinks

rus = RandomUnderSampler(random_state=0, replacement=True)
X_resampled, y_resampled = rus.fit_resample(X, y)
print(sorted(Counter(y_resampled).items()))

# EasyEnsemble和BalanceCascade 变为不均衡数据预处理方法EasyEnsembleClassifier和BalancedBaggingClassifier
from imblearn.ensemble import BalancedBaggingClassifier,BalancedRandomForestClassifier,EasyEnsembleClassifier,RUSBoostClassifier
ee = EasyEnsembleClassifier(random_state=0)
model = ee.fit(X, y)


cc = ClusterCentroids(random_state=0)
X_resampled, y_resampled = cc.fit_resample(X, y)
print(sorted(Counter(y_resampled).items()))


bc = BalancedBaggingClassifier(random_state=0)
model = bc.fit(X, y)
# print(sorted(Counter(y_resampled[0]).items()))

nm1 = NearMiss(version=1)
X_resampled_nm1, y_resampled = nm1.fit_resample(X, y)
print(sorted(Counter(y_resampled).items()))

enn = EditedNearestNeighbours()
X_resampled, y_resampled = enn.fit_resample(X, y)
print(sorted(Counter(y_resampled).items()))

tl = TomekLinks()
X_resampled, y_resampled = tl.fit_resample(X, y)
print(sorted(Counter(y_resampled).items()))
三、混合采样(Synthetic Sampling)

当由边界的样本与其他样本进行过采样差值时, 很容易生成一些噪音数据。因此, 在过采样之后需要对样本进行清洗。即将前面的过采样和欠采样一起进行的混合模式,常见的有 SMOTEENN和SMOTETomek。

''' 
   SMOTEENN:SMOTE(过采样)+EditedNearestNeighbours(欠采样)
   SMOTETomek:SMOTE(过采样)+Tomek(欠采样)
'''
from imblearn.combine import SMOTEENN
smote_enn = SMOTEENN(random_state=0)
X_resampled, y_resampled = smote_enn.fit_resample(X, y)
print(sorted(Counter(y_resampled).items()))

from imblearn.combine import SMOTETomek
smote_tomek = SMOTETomek(random_state=0)
X_resampled, y_resampled = smote_tomek.fit_resample(X, y)
print(sorted(Counter(y_resampled).items()))

  • 13
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值