不平衡数据集之过采样实现方案总结
文章目录
一、数据不平衡问题
在很多真实场景下,数据集往往是不平衡的。也就是说,在数据集中,有一类含有的数据要远远多于其他类的数据(类别分布不平衡)。
在贷款场景下,信用正常客户的数据是要远远多于欺诈客户的。
考虑一个简单的例子,10万正样本(正常客户标签为0)与1000个负样本(欺诈客户标签为1),正负样本比列为100:1,如果直接带入模型中去学习,每一次梯度下降如果使用全量样本,负样本的权重只有不到1/100,即使完全不学习负样本的信息,准确率也有超过99%,所以显然绝不能以准确率来衡量模型的效果。并且即使使用KS或者AUC来度量模型的表现,依然没法保证模型能将负样本很好的学习。实际上需要得到一个分类器,既能对于正例有很高的准确率,同时又不会影响到负例的准确率。
类似于上面例子中的数据集,由于整个数据空间中,正例和负例的数据就是不平衡的。因此,这样的不平衡数据集的产生往往是内在的。同时,也有很多其他的因素会造成数据的不平衡,例如,时间,存储等。由于这些原因产生不平衡的数据集往往被称为外在的。除了数据集的内在和外在,可能还要注意到数据集的相对不平衡以及绝对不平衡。假设上述例子中的数据集有100000条数据,负例和正例的比例为100:1,只包含1000个正例。明显的,不能说1000个数据就是绝对小的,只不过相对于负例来说,它的数量相对较少。因此,这样的数据集被认为是相对不平衡的。
二、过采样算法
- 朴素随机过采样
- SMOTE
- ADASYN
- ……
1.朴素随机过采样
朴素随机过采样算法(Random Oversampling)是一种处理不平衡数据集的方法,它通过在少数类样本中随机选择样本进行复制,从而增加少数类样本的数量。这有助于平衡不同类别之间的样本分布,提高模型对少数类的学习能力。
1. 选择少数类样本:从少数类中随机选择一些样本。
2. 复制样本:对选择的样本进行复制,使得该少数类的样本数量增加。
3. 重复过程:重复上述步骤,直到少数类样本数量达到满足要求的程度。
这个过程实质上是对原始少数类样本的简单复制,以增加该类别的样本数量,使得在训练模型时,模型更关注少数类样本,从而提高模型对少数类的识别能力。
代码如下(示例):
# 朴素随机过采样实现代码
from imblearn.over_sampling import RandomOverSampler
from sklearn.datasets import make_classification
from collections import Counter
# 创建不平衡数据集
X, y = make_classification(n_classes=2, class_sep=2, weights=[0.1, 0.9],
n_informative=3, n_redundant=1, flip_y=0,
n_features=20, n_clusters_per_class=1,
n_samples=1000, random_state=42)
# 朴素随机过采样
ros = RandomOverSampler(random_state=42)
X_resampled, y_resampled = ros.fit_resample(X, y)
2.SMOTE
- regular(标准的 SMOTE)
- borderline1
- borderline2
- svm
SMOTE(Synthetic Minority Over-sampling Technique)是一种用于处理不平衡数据集的过抽样方法,它通过合成新的少数类样本来平衡类别分布。SMOTE的主要思想是对于每个少数类样本,随机选择其k个最近邻的样本,然后在这些样本之间插入新的合成样本。这样可以有效地增加少数类样本的数量,提高模型对少数类的性能。
注意:SMOTE容易出现过拟合和高方差的问题,而且容易制造出重叠的数据
代码如下(示例):
from imblearn.over_sampling import SMOTE
# 使用SMOTE进行过抽样
smote = SMOTE(sampling_strategy='auto', k_neighbors=5, random_state=42)
X_smote, y_smote = smote.fit_resample(X, y)
3.BorderlineSMOTE
- Borderline-SMOTE是对SMOTE的改进,它仅在那些靠近类别边界的样本上应用SMOTE。这样可以减少在类别内部生成的合成样本数量,减少可能引入的噪音。
- Borderline-SMOTE更加关注在类别边界附近的样本,避免了在类别内部生成过多合成样本的问题,从而提高了生成样本的质量。
Borderline-SMOTE1 VS Borderline-SMOTE2
1、Borderline-SMOTE1 (borderline1):
- 识别边界样本:首先确定少数类样本中的边界样本。边界样本定义为那些大部分邻居是多数类样本的少数类样本。具体来说,如果一个少数类样本的k最近邻中有一半以上是多数类样本,则将其视为边界样本。
- 生成合成样本:然后,仅对这些边界样本应用SMOTE算法。这意味着在边界样本和它们的少数类邻居之间生成新的合成样本。
- 目的:Borderline-SMOTE1的主要目的是加强少数类在其决策边界处的表示,因为这些区域是分类器最可能出错的地方。
2、Borderline-SMOTE2(borderline2)
- 识别边界样本:与Borderline-SMOTE1相同,首先识别少数类中的边界样本。
- 生成合成样本:在生成合成样本时,Borderline-SMOTE2与Borderline-SMOTE1略有不同。它不仅在边界样本和它们的少数类邻居之间生成新样本,还可能在边界样本和多数类邻居之间生成新样本。
- 目的:这种方法的思想是,通过在边界样本附近生成更多的少数类样本,无论这些样本是与少数类邻居还是多数类邻居相邻,都能更好地捕捉少数类与多数类之间的复杂边界。
在实际应用中,可能需要对这两种方法进行试验和对比,以确定哪种方法更适合特定的数据集和分类任务。
# Borderline-SMOTE1
from imblearn.over_sampling import BorderlineSMOTE
borderline1_smote = BorderlineSMOTE(sampling_strategy='auto', k_neighbors=5, random_state=42, kind='borderline-1')
X_borderline1, y_borderline1 = borderline1_smote.fit_resample(X, y)
# Borderline-SMOTE2
from imblearn.over_sampling import BorderlineSMOTE
borderline2_smote = BorderlineSMOTE(sampling_strategy='auto', k_neighbors=5, random_state=42, kind='borderline-2')
X_borderline2, y_borderline2 = borderline2_smote.fit_resample(X, y)
Counter(y_borderline2)
4.ADASYN
ADASYN(Adaptive Synthetic Sampling Approach for Imbalanced Learning)算法是一种用于处理不平衡数据集的过采样技术。其核心思想是为少数类样本生成更多的合成样本,特别是在那些难以正确分类的区域。
1、计算每个少数类样本的不平衡度:对于每个少数类样本,计算其周围区域内多数类样本与少数类样本的比例,以此确定每个少数类样本的不平衡程度。
2、根据不平衡度生成新样本:对于每个少数类样本,根据其不平衡度来决定需要生成的合成样本的数量。不平衡度越高的样本,生成的合成样本就越多。
3、生成合成样本:对于每个少数类样本,随机选择其k近邻中的一个点,然后在这两个点之间随机生成新的样本点。
ADASYN核心思想就是使用密度分布来确定每个少数类样本产生多少数量的合成数据
from imblearn.over_sampling import ADASYN
# 使用ADASYN进行过采样
adasyn = ADASYN(sampling_strategy='auto', random_state=42, n_neighbors=5)
X_ada, y_ada = adasyn.fit_resample(X, y)
5.SVMSMOTE
SVMSMOTE(Support Vector Machine Synthetic Minority Over-sampling Technique)是一种基于SMOTE算法的变体,使用支持向量机(SVM)来确定对少数类样本合成新样本最有价值的区域。其核心思想是利用SVM的边界决策特性来识别少数类样本与多数类样本之间的边界,然后在这些关键区域增加新的合成少数类样本,以改善分类模型的性能。在决策边界附近增加更多的少数类样本可以帮助模型更好地学习边界,从而提高分类性能。
SVMSMOTE算法的实现中,主要有以下几个可调节的参数:
- k_neighbors:用于SMOTE算法中的k最近邻参数,确定每个少数类样本在合成新样本时参考的邻近样本数量。
- svm_estimator:一个SVM模型实例,用于在训练数据上识别支持向量。可以调整SVM的参数,如C、kernel等,以优化边界识别。
- m_neighbors:用于确定哪些少数类样本会被选作合成新样本的候选者。通常,这个参数会影响到选择作为SMOTE合成起点的样本数量。【用来确定一个少数类样本是否位于分类的决策边界附近,如果一个少数类样本周围有较多的多数类邻居(超过m_neighbors指定的数量),则可以认为它位于决策边界附近。】
- n_jobs:指定并行计算时使用的CPU核心数。对于大数据集,增加n_jobs可以显著加快算法的执行速度
from imblearn.over_sampling import SVMSMOTE
from sklearn.svm import SVC
# 初始化SVMSMOTE
svm_smote = SVMSMOTE(svm_estimator=SVC(kernel='linear'), k_neighbors=5, random_state=42, m_neighbors=10)
# 应用SVMSMOTE
X_res, y_res = svm_smote.fit_resample(X, y)
6.KMeansSMOTE
KMeansSMOTE(K-Means SMOTE)是一种结合了K-Means聚类和SMOTE(Synthetic Minority Over-sampling Technique)的技术,用于解决类不平衡问题,特别是在少数类样本极其稀少的情况下。这种方法首先使用K-Means算法对少数类样本进行聚类,然后在每个聚类内部使用SMOTE方法生成合成样本。
K-Means聚类:对少数类样本进行K-Means聚类。聚类的目的是识别出少数类样本中的不同子群体,因为在不同的区域内,少数类样本的分布和多数类样本的分布可能不同。
SMOTE过程:在每个聚类内,根据其密度和大小,应用SMOTE算法生成新的合成样本。SMOTE是通过在少数类样本之间插入新样本来增加少数类的样本数。新样本是通过选择一个样本和其最近邻之间的线段上的一个点来合成的。【在簇中心附近应用SMOTE算法生成合成样本】
from imblearn.over_sampling import KMeansSMOTE
import warnings
# 忽略所有警告
warnings.filterwarnings("ignore")
# 应用KMeansSMOTE
kms = KMeansSMOTE(random_state=42, kmeans_estimator=10, sampling_strategy='auto')
X_res, y_res = kms.fit_resample(X, y)
7.Tomek links
Tomek links是一种可以用于数据清洗的下采样技术,主要用于处理分类问题中的类不平衡问题。原理上,它通过查找并删除特定的样本对来减少样本数量,目的是创建一个可以更好地区分少数类和多数类的空间。
Tomek link是一对相邻的样本,这对样本中一个属于少数类,另一个属于多数类。如果一个样本的最近邻属于不同的类,则这两个样本被认为是一个Tomek链接。多数情况下,我们会从数据集中移除这些Tomek Links中的多数类样本以更好地区分两类。
Tomek Links经常与其他采样方法结合使用,特别是与SMOTE(Synthetic Minority Over-sampling Technique)结合,形成一个非常流行的处理不平衡数据集的策略
- 首先使用SMOTE增加少数类样本:SMOTE通过在少数类样本之间插入新的合成样本来增加少数类样本的数量,这有助于平衡类分布。但是,SMOTE可能会在多数类和少数类之间的边界区域生成一些合成样本,这可能导致分类器的决策边界变得模糊。
- 然后使用Tomek Links去除重叠样本:在SMOTE生成新样本之后,使用Tomek
Links可以去除一些边界区域的多数类样本,从而清除重叠区域,使类别之间的分界更加清晰。
from imblearn.under_sampling import TomekLinks
tl = TomekLinks(sampling_strategy="all")
X_res, y_res = tl.fit_resample(X_borderline1, y_borderline1)