不平衡处理方法介绍

处理数据样本不平衡问题是在机器学习和数据挖掘任务中常见的挑战之一。以下是一些常用的数据样本不平衡处理方法:

  1. 过采样(Over-sampling):
    过采样方法通过增加少数类样本的数量来平衡数据集。常见的过采样方法包括随机复制样本、SMOTE(Synthetic Minority
    Over-sampling Technique)等。
  2. 欠采样(Under-sampling):
    欠采样方法通过减少多数类样本的数量来平衡数据集。常见的欠采样方法包括随机删除样本、Cluster Centroids、NearMiss
    等。
  3. 结合采样(Combining Sampling):
    结合采样方法将过采样和欠采样结合起来,以平衡数据集。常见的结合采样方法包括SMOTEENN、SMOTETomek等。
  4. 类别权重(Class Weighting):
    类别权重方法通过为不同类别赋予不同的权重,调整算法对不同类别的关注程度。可以通过设置样本权重或使用带有类别权重参数的算法来实现。
  5. 集成方法(Ensemble Methods):
    集成方法通过组合多个模型的预测结果来处理数据样本不平衡问题。常见的集成方法包括Bagging、Boosting等。
  6. 阈值调整(Threshold Adjustment):
    阈值调整方法通过调整分类模型的预测阈值来平衡不同类别之间的权衡。可以根据需求调整阈值,使得分类器对少数类样本更敏感。

在实际应用过程中,我们需要根据具体的数据集和问题选择合适的方法。通常,应该通过交叉验证或其他评估方法来比较不同的处理方法,并选择表现最好的方法来解决数据样本不平衡问题。

一、采样类方法

SMOTE采样与简单过采样方法的区别:

SMOTE(Synthetic Minority Over-sampling Technique)采样是一种过采样方法,而过采样(Over-sampling)是一般概念上的方法。下面是 SMOTE 采样与通常的过采样方法之间的区别:

  • SMOTE 采样使用合成样本:SMOTE
    采样通过对少数类样本进行插值来生成合成样本,而不是简单地复制少数类样本。它基于少数类样本之间的线性插值,创建新的合成样本来增加少数类样本的数量。这样可以更好地利用已有的少数类样本,并引入一定程度的多样性。
  • 传统过采样方法简单复制样本:传统的过采样方法是通过简单地复制少数类样本来增加其数量。这种方法没有引入新的样本,仅仅是重复使用已有的少数类样本。这可能导致模型对少数类样本过于敏感,并且没有引入新的多样性。
  • 控制合成样本的数量:SMOTE
    采样可以通过控制合成样本的数量来控制过采样的程度。可以根据需要生成不同数量的合成样本,从而平衡数据集。而传统的过采样方法则是通过简单复制样本来增加数量,不具备这种控制的灵活性。
  • 处理边界样本:SMOTE 采样可以处理边界样本,即位于两个或多个不同类别之间的样本。通过在特征空间中进行插值,SMOTE
    采样可以生成合成样本来更好地表示边界样本的特征分布。传统的过采样方法无法处理边界样本,因为它只是简单地复制样本。

综上所述,SMOTE 采样相比传统的简单复制过采样方法,具有更好的样本多样性和处理边界样本的能力。它通过生成合成样本来增加少数类样本的数量,以平衡数据集并改善分类器的性能。

import numpy as np
from sklearn.datasets import make_classification
from imblearn.over_sampling import RandomOverSampler
from imblearn.under_sampling import RandomUnderSampler
from imblearn.over_sampling import SMOTE

# 生成不平衡数据集
X, y = make_classification(n_samples=1000, n_features=10, weights=[0.9, 0.1], random_state=42)

# 打印原始数据集的类别分布
unique, counts = np.unique(y, return_counts=True)
print("原始数据集类别分布:", dict(zip(unique, counts)))

# 过采样(RandomOverSampler)
over_sampler = RandomOverSampler()
X_over, y_over = over_sampler.fit_resample(X, y)

# 欠采样(RandomUnderSampler)
under_sampler = RandomUnderSampler()
X_under, y_under = under_sampler.fit_resample(X, y)

# SMOTE 采样
smote = SMOTE()
X_smote, y_smote = smote.fit_resample(X, y)

# 打印过采样后的类别分布
unique_over, counts_over = np.unique(y_over, return_counts=True)
print("过采样后的类别分布:", dict(zip(unique_over, counts_over)))

# 打印欠采样后的类别分布
unique_under, counts_under = np.unique(y_under, return_counts=True)
print("欠采样后的类别分布:", dict(zip(unique_under, counts_under)))

# 打印 SMOTE 采样后的类别分布
unique_smote, counts_smote = np.unique(y_smote, return_counts=True)
print("SMOTE 采样后的类别分布:", dict(zip(unique_smote, counts_smote)))

输出:
原始数据集类别分布: {0: 897, 1: 103}
过采样后的类别分布: {0: 897, 1: 897}
欠采样后的类别分布: {0: 103, 1: 103}
SMOTE 采样后的类别分布: {0: 897, 1: 897}

二、类别权重:

类别权重(Class Weighting)是一种解决正负样本不平衡问题的方法,通过调整样本的权重来平衡不同类别之间的重要性。在训练分类器时,通过赋予少数类样本更高的权重,可以增加它们对模型训练的影响,从而提高对少数类的识别能力。常用的机器学习方法中都封装了Class Weighting这个参数用于设置不同类别采样权重。

比如LightGBM算法中:
class_weight(默认值:None):类别权重用于处理类别不平衡的问题。可以指定一个字典或字符串来设置类别权重。例如,可以使用 ‘balanced’ 来自动平衡权重,或者使用字典 {0: 1, 1: 2} 来设置不同类别的权重比例(LightBGM原生接口不支持传入字典)。

import lightgbm as lgb
from sklearn.utils import class_weight

# 计算类别权重
class_weights = class_weight.compute_class_weight('balanced', classes=np.unique(y), y=y)

# 创建 LightGBM 数据集
lgb_train = lgb.Dataset(X, label=y)

# 设置类别权重
params = {
    'objective': 'binary',
    'metric': 'binary_logloss',
    'class_weight': class_weights   # 'class_weight': 'balanced'
}

# 训练模型
model = lgb.train(params, lgb_train)

三、集成方法

集成方法(Ensemble Methods)可以在一定程度上解决正负样本不平衡问题。虽然集成方法本身并没有专门针对样本不平衡问题的设计,但通过结合多个分类器或回归器的预测结果,它可以在处理不平衡数据集时提供以下优势:

  1. 增加少数类样本的影响力:
    在正负样本不平衡的情况下,少数类样本往往得不到充分的关注。通过使用集成方法,可以组合多个分类器或回归器的预测结果,其中某些模型可能更加关注少数类样本。这样可以增加少数类样本在最终预测中的影响力,提高对少数类的识别能力。
  2. 减少过拟合风险:
    在样本不平衡问题中,过拟合是一个常见的挑战,特别是在少数类样本稀缺的情况下。集成方法通过结合多个模型的预测结果,可以降低单个模型的过拟合风险。通过对多个模型的预测结果进行平均或投票,集成方法可以更好地适应整个数据分布,减少对少数类样本的过拟合。
  3. 改善决策边界:
    在样本不平衡问题中,分类器通常倾向于偏向多数类样本,导致决策边界的偏移。通过集成多个分类器的预测结果,集成方法可以改善决策边界的位置和形状。集成方法能够综合不同分类器的决策边界,产生更准确且更平衡的分类结果。

需要注意的是,虽然集成方法可以在一定程度上解决正负样本不平衡问题,但对于极度不平衡的数据集,仍可能需要额外的处理方法,如过采样、欠采样或 SMOTE 等。集成方法的性能还受到基分类器的质量和多样性的影响,因此选择合适的基分类器也是重要的。在实际应用中,应该根据具体问题和数据集的特点,综合考虑不同的方法来处理正负样本不平衡问题。

四、阈值调整

阈值调整(Threshold Adjustment)是一种用于解决正负样本不平衡问题的方法,通过调整分类器的预测阈值来平衡不同类别之间的权衡。在二分类问题中,分类器通常将概率或得分高于阈值的样本划分为正类,低于阈值的样本划分为负类。但是在正负样本不平衡的情况下,这个默认的阈值可能无法达到我们期望的结果。

阈值调整的目标是找到一个更适合的阈值,使得分类器在不同类别之间取得更好的平衡。具体的方法如下:

  1. ROC曲线和AUC:
    首先,可以使用 ROC 曲线(Receiver Operating Characteristic)和 AUC(Area Under
    the Curve)作为评估指标来衡量分类器在不同阈值下的性能。ROC 曲线是以真阳率(True Positive
    Rate)为纵轴,假阳率(False Positive Rate)为横轴绘制的曲线,AUC 表示 ROC
    曲线下的面积,越接近1表示分类器性能越好。
  2. 混淆矩阵和评估指标:
    使用混淆矩阵来衡量分类器在不同阈值下的准确性。通过调整阈值,可以计算出不同的真阳性率(TPR)、假阳性率(FPR)、准确率(Precision)、召回率(Recall)等评估指标,并选择最合适的阈值。
  3. 基于业务需求:
    根据具体的业务需求和应用场景,可以通过设置不同的阈值来平衡分类器对正负样本的重视程度。例如,在医疗诊断中,可能更关注对少数类样本的准确识别,因此可以将阈值调低以增加真阳性率。
  4. 使用代价敏感的学习算法:
    一些学习算法支持代价敏感的学习,可以通过设置不同类别的误分类代价来调整分类器对不平衡样本的处理。这样,分类器在决策时会考虑到不同类别的权衡。

阈值调整是一种简单而有效的方法,可以通过调整分类器的预测阈值来改善正负样本不平衡问题。通过合理的阈值选择,可以更好地平衡分类器对不同类别的关注程度,从而提高模型性能。但需要注意的是,阈值调整可能会导致准确率和召回率之间的权衡,需要根据具体需求权衡利弊并进行调优。