不平衡数据集的处理
python包:imblearn,参考文档:imbalanced-learn
目录
一、上采样方法(imblearn.over_sampling)
二、下采样方法(imblearn.under_sampling)
可控制的下采样方法(the controlled under-sampling techniques)
数据清洗方法(the cleaning under-sampling techniques)
2.6、RepeatedEditedNearestNeighbours
2.10、NeighbourhoodCleaningRule
2.11、InstanceHardnessThreshold
四、下采样多模型融合方法(imblearn.ensemble)
4.3、BalancedRandomForestClassifier
一、上采样方法(imblearn.over_sampling)
增加少数类的样本。
1.1、RandomOverSampler
通过对少数类样本进行有放回地随机采样来生成少数类的样本。
from imblearn.over_sampling import RandomOverSampler
ros = RandomOverSampler(sampling_strategy={0: 100, 1: 100}, random_state=42)
X_res, y_res = ros.fit_resample(X, y)
1.2、SMOTE
Synthetic Minority Oversampling Technique (SMOTE),通过插值来生成新样本,对于每个少数类样本计算其K个最近的少数类邻居,然后根据采样比率随机选择若干邻居,最后在少数类样本与邻居样本之间进行插值生成新样本。
from imblearn.over_sampling import SMOTE
sm = SMOTE(random_state=42)
X_res, y_res = sm.fit_resample(X, y)
1.3、ADASYN
Adaptive Synthetic (ADASYN),也是通过插值来生成新样本,ADASYN更关注于在被K最近邻分类器误分类为多数类的少数类样本(离群点)旁生成新样本,一个少数类样本周围的多数类样本越多,则赋予该少数类样本越大的权重,在该少数类样本旁生成越多的样本,生成过程与SMOTE类似,从少数类样本的K个最近的少数类邻居中随机选择一个少数类邻居进行插值,根据该少数类样本的权重对该少数类样本重复插值若干次。
from imblearn.over_sampling import ADASYN
ada = ADASYN(random_state=42)
X_res, y_res = ada.fit_resample(X, y)
1.4、BorderlineSMOTE
由于SMOTE算法随机选择少数类样本来生成新样本,没有考虑到所选少数类样本周围的情况,因此可能存在两个问题:
- 所选的少数类样本周围也都是少数类样本,这样合成的新样本不会提供太多有用信息;
- 所选的少数类样本周围都是多数类样本,这样的样本可能是噪声,生成的新样本可能会与周围多数类样本重叠。
因此BorderlineSMOTE算法在SMOTE算法上进行改进,只使用处于边界上的少数类样本来合成新样本,算法首先将所有少数类样本划分为三类,分别是:
- noise:噪声样本,即少数类样本的周围K个近邻都是多数类样本;
- danger:危险样本,即少数类样本的周围K个近邻中有一半及以上为多数类样本;
- safe:安全样本,即少数类样本的周围K个近邻中有一半以上为少数类样本。
然后算法使用danger样本根据SMOTE算法来生成新样本,根据在生成新样本时选择邻居类别的不同,BorderlineSMOTE又分为borderline-1和
borderline-2,前者在K近邻中选择少数类样本来进行插值,后者选择任意类别样本来进行插值。
from imblearn.over_sampling import BorderlineSMOTE
sm = BorderlineSMOTE(random_state=42, kind='borderline-1')
X_res, y_res = sm.fit_resample(X, y)
1.5、SVMSMOTE
SVMSMOTE用SVM分类器来寻找支持向量,然后在支持向量的基础上生成新样本。类似于BorderlineSMOTE,SVMSMOTE也将少数类样本划分为noise、danger和safe三类。
from imblearn.over_sampling import SVMSMOTE
sm = SVMSMOTE(random_state=42)
X_res, y_res = sm.fit_resample(X, y)
1.6、KMeansSMOTE
KMeansSMOTE先对样本进行KMeans聚类,然后根据簇密度来对不同簇的少数类样本进行合成。具体包括三个步骤:
- 聚类:使用KMeans将所有样本聚为K个簇;
- 过滤:选择用于上采样的簇,保留具有高比例少数类样本的簇;
- 上采样:应用SMOTE在每个选定的簇中生成新样本,对于少数类样本越稀疏的簇,生成的少数类样本越多。
from imblearn.over_sampling import KMeansSMOTE
sm = KMeansSMOTE(random_state=42)
X_res, y_res = sm.fit_resample(X, y)
1.7、SMOTENC
Synthetic Minority Oversampling Technique for Nominal and Continuous (SMOTE-NC),用于处理分类特征。由于分类特征无法计算插值,SMOTENC会在合成新样本时采用K个近邻样本中出现频率最高的分类特征作为新样本的分类特征,使用时需指定分类特征的位置。
from imblearn.over_sampling import SMOTENC
sm = SMOTENC(random_state=42, categorical_features=[18, 19])
X_res, y_res = sm.fit_resample(X, y)
二、下采样方法(imblearn.under_sampling)
减少多数类的样本。
样本生成方法(prototype generation)
2.1、ClusterCentroids
使用KMeans对各类别样本进行聚类,然后将聚类中心作为新生成的样本,以此达到下采样的效果。
from imblearn.under_sampling import ClusterCentroids
cc = ClusterCentroids(random_state=42)
X_res, y_res = cc.fit_resample(X, y)
样本选择方法(prototype selection)
样本选择方法分为两类:第一类为可控制的下采样方法,即下采样的数量可人为指定;第二类为数据清洗方法,下采样的数量不可指定。
可控制的下采样方法(the controlled under-sampling techniques)
2.2、RandomUnderSampler
通过对多数类样本进行有放回或无放回地随机采样来选择部分多数类样本。
from imblearn.under_sampling import RandomUnderSampler
rus = RandomUnderSampler(random_state=42)
X_res, y_res = rus.fit_resample(X, y)
2.3、NearMiss
NearMiss增加了一些启发式的规则来选择样本,通过参数version可以指定3种不同的规则:
- NearMiss-1:选择到最近的N个少数类样本的平均距离最小的多数类样本;
- NearMiss-2:选择到最远的N个少数类样本的平均距离最小的多数类样本;
- NearMiss-3:首先,保留每个少数类的M个最近邻样本,然后,选择离N个最近邻样本的平均距离最大的多数类样本。
from imblearn.under_sampling import NearMiss
nm = NearMiss(version=1)
X_res, y_res = nm.fit_resample(X, y)
数据清洗方法(the cleaning under-sampling techniques)
2.4、TomekLinks
如果两个样本点互为最近邻且分属于不同类别,则在它们之间形成Tomek’s link,通过参数sampling_strategy可以选择剔除的样本类别。
from imblearn.under_sampling import TomekLinks
tl = TomekLinks(sampling_strategy='auto') # 移除多数类样本
# tl = TomekLinks(sampling_strategy='all') # 多数类样本和少数类样本都移除
X_res, y_res = tl.fit_resample(X, y)
2.5、EditedNearestNeighbours
对于需要下采样的类别的每个样本,计算其K个最近邻样本,若
- 超过一半的邻居样本不属于该类别(kind_sel='mode'),或者
- 所有邻居样本都不属于该类别(kind_sel='all'),
则剔除该样本。
from imblearn.under_sampling import EditedNearestNeighbours
enn = EditedNearestNeighbours(kind_sel='mode')
# enn = EditedNearestNeighbours(kind_sel='all')
X_res, y_res = enn.fit_resample(X, y)
2.6、RepeatedEditedNearestNeighbours
重复EditedNearestNeighbours多次,参数max_iter控制迭代次数。
from imblearn.under_sampling import RepeatedEditedNearestNeighbours
renn = RepeatedEditedNearestNeighbours(max_iter=100)
X_res, y_res = renn.fit_resample(X, y)
2.7、AllKNN
与RepeatedEditedNearestNeighbours的不同之处在于,在每次迭代过程中,不断增加最近邻的数目。
from imblearn.under_sampling import AllKNN
allknn = AllKNN()
X_resampled, y_resampled = allknn.fit_resample(X, y)
2.8、CondensedNearestNeighbour
使用1近邻方法迭代判断一个样本是否应该被剔除,具体算法步骤如下:
- 将所有少数类样本放入集合C;
- 从目标类(待下采样的类)中选择一个样本放入C,其余的该类样本放入集合S;
- 逐样本遍历集合S,训练1近邻分类器,对S中的所有样本进行分类;
- 将S中错误分类的样本加入C;
- 重复上述过程直到没有再加入C中的样本。
from imblearn.under_sampling import CondensedNearestNeighbour
cnn = CondensedNearestNeighbour(random_state=42)
X_resampled, y_resampled = cnn.fit_resample(X, y)
2.9、OneSidedSelection
CondensedNearestNeighbour对噪声敏感,容易将噪声样本加入集合C。相反地,OneSidedSelection使用TomekLinks移除噪声样本,除此之外,它将1近邻规则应用于所有样本,被误分类的样本将被加入集合C,在集合S上不进行迭代。
from imblearn.under_sampling import OneSidedSelection
oss = OneSidedSelection(random_state=42)
X_resampled, y_resampled = oss.fit_resample(X, y)
2.10、NeighbourhoodCleaningRule
在EditedNearestNeighbours的基础上进行改进,对所有样本计算其K个最近邻样本,
- 若当前样本为多数类样本,且超过一半的最近邻样本与其类别不同,则剔除该样本;
- 若当前样本为少数类样本,且超过一半的最近邻样本与其类别不同,则剔除最近邻样本中的多数类样本。
from imblearn.under_sampling import NeighbourhoodCleaningRule
ncr = NeighbourhoodCleaningRule()
X_resampled, y_resampled = ncr.fit_resample(X, y)
2.11、InstanceHardnessThreshold
InstanceHardnessThreshold使用所有样本训练一个分类器,然后将预测概率低的样本剔除。
from imblearn.under_sampling import InstanceHardnessThreshold
iht = InstanceHardnessThreshold(random_state=42,
estimator=LogisticRegression(
solver='lbfgs', multi_class='auto'))
X_resampled, y_resampled = iht.fit_resample(X, y)
三、上、下采样结合(imblearn.combine)
先进行上采样,然后使用下采样中的数据清洗方法剔除噪声。
3.1、SMOTEENN
先用SMOTE上采样,再用EditedNearestNeighbours剔除噪声。
from imblearn.combine import SMOTEENN
smote_enn = SMOTEENN(random_state=42)
X_resampled, y_resampled = smote_enn.fit_resample(X, y)
3.2、SMOTETomek
先用SMOTE上采样,再用TomekLinks剔除噪声。
from imblearn.combine import SMOTETomek
smote_tomek = SMOTETomek(random_state=42)
X_resampled, y_resampled = smote_tomek.fit_resample(X, y)
四、下采样多模型融合方法(imblearn.ensemble)
4.1、EasyEnsembleClassifier
4.2、BalancedBaggingClassifier
4.3、BalancedRandomForestClassifier
4.4、RUSBoostClassifier
未完待续...