非平衡数据处理方式

非平衡数据处理方式

1. 什么是非平衡数据

非平衡数据(Imbalanced Data)指的是在一个数据集中,不同类别的样本数量极不相等。在一个典型的非平衡数据场景中,一个或少数几个类别(称为多数类)的样本数量远远超过其他类别(称为少数类)的样本数量。

这种情况在现实世界的数据集中很常见,尤其是在分类问题中,比如欺诈检测、疾病诊断、文本分类等。例如,在数十亿的金融交易中,只有少数被认定为欺诈(fraud)。 欺诈事件可能只占很小的比例,如0.05%或1%,远远小于正常交易的比例。在数据集中占很大比例的类被称为多数类。那些占比例较小的类是少数类

非平衡数据会导致机器学习模型的性能偏向于多数类,从而忽略少数类,这是因为大多数机器学习算法的目标是最大化整体的准确率,而不是平衡不同类别的识别率。

2. 为什么模型会偏向多数类

这个其实也很好理解,因为模型的目标函数是基于最小化、整体错误率或最大化整体准确率设计的,那因为多数类的样本远远超过少数类模型,很自然的会倾向于优化对多数类的预测,即使模型对少数类的预测表现不佳,但整体的准确率仍然会高

3. 处理非平衡数据的方式

3.1 欠采样(UnderSampling)

欠采样(Undersampling)是处理不平衡数据集的一种技术,特别是在一个类别的样本远多于另一个类别的情况下。在数据预处理阶段应用,欠采样的目的是通过减少多数类(即样本数量较多的类别)的样本数量来平衡数据集,从而使得多数类和少数类的样本数量接近。

print("原始数据集中各类的样本数:", dict(zip(*np.unique(y, return_counts=True))))

# 初始化RandomUnderSampler对象
rus = RandomUnderSampler(random_state=42)

# 应用欠采样
x_res, y_res = rus.fit_resample(x, y)

print("欠采样后数据集中各类的样本数:", dict(zip(*np.unique(y_res, return_counts=True))))

from sklearn.metrics import ConfusionMatrixDisplay
clf = RandomForestClassifier(max_depth=2, random_state=0).fit(x_res, y_res)
print("F1 Score is ", f1_score(y_test, clf.predict(x_test)))
print("Accuracy Score is ", accuracy_score(y_test, clf.predict(x_test)))
ConfusionMatrixDisplay.from_estimator(clf, x_test, y_test)

欠采样的方法

  • 随机欠采样:最简单的欠采样方法,它随机地从多数类中选择样本进行删除,直到多数类和少数类的样本数量大致相同。
  • 有信息的欠采样:相比随机选择,这种方法根据某种标准(如聚类分析)来选择哪些多数类样本被删除,目的是保留多数类中最有代表性或最有信息量的样本。

欠采样的优点

  • 提高计算效率:减少数据集的大小可以减轻模型训练的计算负担,加快训练速度。
  • 平衡数据集:通过减少多数类样本数量,可以使得分类模型在训练时不会过分偏向多数类,从而可能提高对少数类的识别能力。

欠采样的缺点

  • 丢失信息:随机删除多数类中的样本可能会导致重要信息的丢失,这可能会削弱模型的性能。
  • 可能增加过拟合风险:如果过度欠采样,模型可能会在减少后的数据集上过拟合,导致泛化能力下降。

使用场景

欠采样特别适用于那些多数类样本数量远多于少数类,并且数据集足够大到即使删除一些样本也不会丢失太多信息的情况。在应用欠采样时,应仔细考虑数据的特性和模型的需求,以避免过度丢失信息。

注意事项

  • 应该只在训练集上进行欠采样,而保持测试集不变,以确保测试集能够准确地反映模型在实际应用中的表现。
  • 结合其他技术:欠采样通常与其他数据预处理技术或模型改进措施(如过采样少数类、使用成本敏感学习等)结合使用,以达到最佳的模型性能。

3.2 过采样(OverSampling)

过采样(Oversampling)是处理不平衡数据集的另一种技术,用于增加少数类(即样本数量较少的类别)的样本数量,以平衡类别分布。与欠采样不同,过采样通过增加少数类的样本来实现数据平衡,而不是减少多数类的样本数量。

过采样的方法

  • 随机过采样:这是最简单的过采样方法,通过随机复制少数类中的样本来增加其数量,直到达到与多数类相似的样本数量。

    from imblearn.over_sampling import SMOTE
    # 初始化SMOTE对象
    smote = SMOTE(random_state=42)
    
    # 应用过采样
    x_resampled, y_resampled = smote.fit_resample(x_train, y_train)
    
    # 检查过采样后的类别分布
    print("原始训练集中各类的样本数:", dict(zip(*np.unique(y_train, return_counts=True))))
    print("过采样后训练集中各类的样本数:", dict(zip(*np.unique(y_resampled, return_counts=True))))
    
  • 合成少数过采样技术(SMOTE, Synthetic Minority Over-sampling Technique):与随机过采样不同,SMOTE通过在少数类样本之间插入新的合成样本来增加少数类的样本数量。这种方法可以避免简单复制样本可能带来的过拟合问题。

    from imblearn.over_sampling import RandomOverSampler
    
    # 初始化RandomOverSampler对象
    ros = RandomOverSampler(random_state=42)
    
    # 应用过采样
    x_resampled_ros, y_resampled_ros = ros.fit_resample(x_train, y_train)
    
    # 检查过采样后的类别分布
    print("原始训练集中各类的样本数:", dict(zip(*np.unique(y_train, return_counts=True))))
    print("随机过采样后训练集中各类的样本数:", dict(zip(*np.unique(y_resampled_ros, return_counts=True))))
    

过采样的优点

  • 提高少数类样本的表示:过采样可以增加少数类的样本数量,使得分类模型能够更好地学习到少数类的特征。
  • 改善模型性能:通过平衡类别分布,过采样有助于提高模型对少数类的识别能力,从而可能提高整体模型性能。

过采样的缺点

  • 可能导致过拟合:特别是在随机过采样中,简单复制少数类样本可能会使模型过分关注这些重复的样本,从而导致过拟合。
  • 增加计算负担:增加数据集的大小会增加模型训练的计算负担。

使用场景

过采样适用于少数类样本非常少,而数据集总体不是很大的情况。在这种情况下,简单地删除多数类样本可能会导致训练数据不足,而通过增加少数类样本可以在不损失多数类信息的情况下平衡数据集。

注意事项

  • 数据多样性:在使用过采样时,特别是应用SMOTE等技术时,需要注意保持数据的多样性,避免生成的合成样本过于集中。
  • 仅对训练数据过采样:与欠采样一样,过采样也应该只应用于训练数据,以避免影响模型在实际应用中的表现。
  • 结合其他技术:为了达到最佳的模型性能,过采样通常与其他数据预处理技术或模型改进措施结合使用。

3.3 混合过采样和欠采样

混合过采样和欠采样的方式结合了过采样和欠采样两种技术,以应对不平衡数据集中存在的类别不平衡问题

优点:

  • 兼顾多数类和少数类样本:混合过采样和欠采样同时处理多数类和少数类样本,能够更全面地平衡数据集,减少类别不平衡导致的问题。
  • 减少过拟合风险:欠采样可以减少多数类样本的数量,有助于防止模型过度拟合于多数类样本,提高模型的泛化能力。
  • 保留更多信息:通过过采样和欠采样的结合,可以保留更多的原始数据信息,相比单独使用过采样或欠采样,更有可能得到更准确的模型。

缺点:

  • 计算复杂度增加:混合过采样和欠采样通常需要更多的计算资源,因为它要处理更复杂的数据集。特别是在数据集很大的情况下,计算成本可能会很高。
  • 信息损失:欠采样会删除多数类样本,可能会导致信息的丢失,从而影响模型性能。

适用场景:

  • 严重不平衡的数据集:混合过采样和欠采样适用于类别不平衡问题严重的数据集,其中少数类样本数量远远少于多数类样本数量的情况。
  • 需要高泛化能力的模型:对于需要在少数类样本上有较高性能并且泛化能力较强的模型,混合过采样和欠采样可以是一个合适的选择。
  • 计算资源充足的情况:由于混合过采样和欠采样通常需要更多的计算资源,因此在计算资源充足的情况下,可以考虑使用这种方法来处理不平衡数据集。

3.4 调整类权重

具体来说,调整权重的方法是在模型训练过程中,通过为不同类别的样本设置不同的权重,使得模型更加关注少数类样本,从而减少对多数类样本的过度拟合。这样可以提高模型对少数类的预测准确性,从而改善模型的整体性能。

在实际应用中,通常可以通过设置类别权重的参数来实现调整权重的操作。例如,在Scikit-learn库中,可以通过在模型初始化时设置**class_weight参数来指定类别权重。这个参数可以是一个字典,将类别标签映射到对应的权重值,也可以是一个字符串,表示使用预先定义的权重策略,例如balanced**表示自动计算权重以平衡类别。

weighted_clf = RandomForestClassifier(class_weight='balanced')
# 需要指定这个权重 class_weight={0:2,1:1}
# 可以使用网格搜索找到最佳的权重
weighted_clf.fit(x_train, y_train)
ConfusionMatrixDisplay.from_estimator(weighted_clf, x_test, y_test)
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import GridSearchCV

# 定义参数网格
param_grid = {
    'class_weight': [{0: 1, 1: w} for w in range(1, 5)]  # 尝试不同的类别权重组合
}

# 初始化随机森林分类器
rf_clf = RandomForestClassifier(random_state=0)

# 初始化网格搜索对象
grid_search = GridSearchCV(estimator=rf_clf, param_grid=param_grid, cv=5, scoring='f1')

# 执行网格搜索
grid_search.fit(x_train, y_train)

# 获取最佳模型
best_rf_clf = grid_search.best_estimator_

# 输出最佳参数
print("最佳类别权重组合:", grid_search.best_params_)

# 输出最佳模型的性能指标
print("最佳模型的 F1 分数:", grid_search.best_score_)

# 使用最佳模型进行预测
y_pred = best_rf_clf.predict(x_test)

优点:

  • 平衡数据集:调整权重可以帮助平衡数据集中不同类别的样本数量,从而减少由于不平衡数据集带来的问题,如模型过度偏向多数类的情况。
  • 提高模型性能:通过使模型更关注少数类样本,调整权重可以提高模型对少数类的识别能力,从而提高模型的整体性能。
  • 简单易实现:在大多数机器学习框架中,调整权重都是一种简单易实现的方法,通常只需要设置相应的参数即可实现。

缺点:

  • 可能导致过拟合:如果调整权重不合适,可能会导致模型在训练集上过度拟合,使得模型在未知数据上的泛化性能下降。
  • 需要调参:调整权重需要根据数据集的特点和模型的需求来选择合适的权重值或策略,这需要进行一定的调参工作。

使用场景:

  • 不平衡数据集:调整权重通常适用于处理不平衡数据集的情况,特别是当少数类样本数量远远少于多数类样本数量时。
  • 重视少数类样本:当任务中的少数类样本对模型性能有重要影响时,调整权重可以帮助模型更好地学习少数类样本的特征。
  • 处理二分类问题:调整权重主要应用于二分类问题,对于多分类问题,通常需要进行额外的处理和调整。
  • 22
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值