
作者提供图片
引言
机器学习新手几乎立刻就能发现一个问题:并非所有数据集都是平等的。
现在这可能对你来说很明显,但在你着手处理真实世界数据集上的机器学习项目之前,你是否考虑过这个问题?例如,如果某种罕见疾病只影响1%的人口,那么一个总是预测“无疾病”的预测模型,即使它有99%的准确率,还会被认为是有效的吗?当然不会。
在机器学习中,不平衡数据集可能会成为模型性能的障碍,而且往往看似难以克服。许多常见的机器学习算法都期望数据分布中的类别具有相似的代表性。在不平衡数据集上训练的机器学习模型往往过度偏向多数类,导致少数类明显代表不足——而当数据需要采取行动时,少数类往往更重要。
这些严重偏斜的数据集在实际应用中随处可见,从对抗罕见疾病(我们的数值数据稀缺且难以获取)到金融领域的欺诈检测(大多数支付都不是欺诈性的)。本文旨在介绍5种可靠的策略来管理类别不平衡数据。
1. 重采样技术
重采样可以通过增加少数类样本或移除多数类样本来平衡类别。
过采样不常见类别的常用技术之一是创建该未充分代表类别的新样本。随机过采样是一种简单的方法,通过复制现有样本来为不常见类别创建新样本。然而,任何熟悉机器学习基础知识的人都会立即注意到过拟合的风险。更复杂的方法包括合成少数过采样技术(SMOTE),它通过在现有少数类样本之间进行插值来构建新样本。
也许不足为奇的是,对更常见类别进行欠采样的技术涉及从中移除样本。例如,随机欠采样要求随机丢弃更常见类别的一些样本。然而,这种欠采样可能会导致信息丢失。为了减轻这种情况,可以使用更复杂的欠采样方法,如Tomek links或邻域清理规则(NCR),这些方法旨在移除接近或与少数样本重叠的多数样本,同时具有在类别之间创建更清晰边界和在保留重要信息的同时可能减少噪声的额外好处。
让我们来看一个使用imbalanced-learn库实现的SMOTE和随机欠采样的基本示例。
1 2 3 4 5 6 7 8 9 10 11 |
from imblearn.over_sampling import SMOTE from imblearn.under_sampling import RandomUnderSampler # 假设 X 是你的特征矩阵,y 是你的目标向量 # SMOTE smote = SMOTE(random_state=42) X_resampled, y_resampled = smote.fit_resample(X, y) # 随机欠采样 rus = RandomUnderSampler(random_state=42) X_resampled, y_resampled = rus.fit_resample(X, y) |
每种方法都有其优缺点。需要强调的是,过采样可能导致过拟合,特别是简单的复制,而欠采样可能会丢弃潜在有用的信息。通常,结合使用多种技术能获得最佳结果。
2. 算法集成方法
集成方法涉及结合多个模型以生成一个对你想要预测的类别更强的整体模型;此策略对于不平衡数据问题很有用,特别是当不平衡类别是你特别感兴趣的类别时。
一种集成学习形式称为装袋(bootstrap aggregating)。装袋背后的概念是随机地从你的数据中创建一系列子集,在每个子集上训练一个模型,然后结合这些模型的预测。随机森林算法是装袋的一种特定实现,常用于不平衡数据。随机森林使用相关数据的随机子集创建单独的决策树,引入多个“副本”的数据,并以一种有效的方式结合它们的输出,从而防止过拟合并提高模型的整体泛化能力。
提升是另一种技术,你按顺序在数据上训练模型,每个新创建的模型都试图改进之前模型的错误。对于处理不平衡类别,提升成为一个强大的工具。例如,梯度提升可以训练自己对少数类别的错误分类方法特别敏感,并进行相应调整。
所有这些技术都可以使用常用库在 Python 中实现。以下是随机森林和梯度提升的代码示例。
1 2 3 4 5 6 7 8 9 |
from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier # 随机森林 rf_classifier = RandomForestClassifier(n_estimators=100, class_weight='balanced_subsample') rf_classifier.fit(X_train, y_train) # 梯度提升 gb_classifier = GradientBoostingClassifier(n_estimators=100) gb_classifier.fit(X_train, y_train) |
在上述代码片段中,n_estimators 定义了树或提升阶段的数量,而 RandomForestClassifier 中的 class_weight 通过调整类别权重来处理不平衡类别。
这些方法通过结合多个模型或关注难以分类的实例,本质上处理了不平衡数据。它们通常在没有明确重采样的情况下表现良好,尽管将它们与重采样技术结合使用可以产生更好的结果。
3. 调整类别权重
类别加权正如其名,是一种在模型训练期间为少数类别分配更高权重的技术,以便让模型更多地关注代表不足的类别。
一些机器学习库,如 scikit-learn,实现了类别权重调整。在一个数据集中某个类别比另一个类别出现频率更高的情况下,少数类别的错误分类会受到更大的惩罚。
例如,在逻辑回归中,类别加权可以按如下方式设置。
1 2 3 4 5 6 7 8 9 10 11 |
from sklearn.linear_model import LogisticRegression from sklearn.utils.class_weight import compute_class_weight import numpy as np # 计算权重 class_weights = compute_class_weight('balanced', classes=np.unique(y), y=y) weight_dict = dict(zip(np.unique(y), class_weights)) # 在模型中使用权重 lr_classifier = LogisticRegression(class_weight=weight_dict) lr_classifier.fit(X_train, y_train) |
通过调整类别权重,我们改变了模型对错误分类每个类别的惩罚方式。但请不要担心,这些权重实际上不会影响模型进行预测的方式,只会影响模型在优化过程中更新其权重的方式。这意味着类别权重调整将影响模型在进行预测时采用的损失函数。一个需要考虑的问题是确保少数类别不会被过度打折,因为一个类别可能会被完全“训练掉”。
4. 使用适当的评估指标
在处理不平衡数据时,准确率可能是一个误导性指标。一个总是预测多数类别的模型可能具有高准确率,但在识别少数类别方面完全失败。
相反,可以考虑使用精确率、召回率、F1-分数和受试者工作特征曲线下面积(AUC-ROC)等指标。提醒一下:
- 精确率衡量的是正确识别出的正例的比例。
- 召回率衡量的是实际正例中被正确识别的比例。
- F1-分数是精确率和召回率的调和平均值,提供了一个平衡的度量。
AUC-ROC 对于不平衡数据特别有用,因为它对类别不平衡不敏感。它衡量模型在各种阈值设置下区分不同类别的能力。
混淆矩阵也同样宝贵。它们提供了模型性能的表格摘要,显示了真阳性、假阳性、真阴性和假阴性。
以下是计算这些指标的方法。这应该有助于提醒我们,许多现有的工具在我们处理不平衡类别这种特殊情况时非常有用。
1 2 3 4 5 6 7 8 9 10 11 |
from sklearn.metrics import precision_recall_fscore_support, roc_auc_score, confusion_matrix # 假设 y_true 是真实标签,y_pred 是预测标签 precision, recall, f1, _ = precision_recall_fscore_support(y_true, y_pred, average='binary') auc_roc = roc_auc_score(y_true, y_pred) conf_matrix = confusion_matrix(y_true, y_pred) print(f"精确率: {precision}, 召回率: {recall}, F1: {f1}") print(f"AUC-ROC: {auc_roc}") print("混淆矩阵:") print(conf_matrix) |
请记住,根据你的具体问题选择指标。如果假阳性代价高昂,请侧重于精确率。如果遗漏任何阳性病例是问题,请优先考虑召回率。F1-分数和AUC-ROC 提供了良好的整体性能度量。
5. 生成合成样本
合成样本生成是一种通过创建少数类别的新人工样本来平衡数据集的先进技术。
SMOTE(合成少数过采样技术)是一种流行的生成合成样本的算法。它的工作原理是选择一个少数类别样本,并找到其k个最近邻居。然后通过在选定样本和这些邻居之间进行插值来创建新样本。
以下是使用imblanced-learn库实现SMOTE的一个简单实用示例。
1 2 3 4 |
from imblearn.over_sampling import SMOTE smote = SMOTE(random_state=42) X_resampled, y_resampled = smote.fit_resample(X, y) |
ADASYN(自适应合成)和BorderlineSMOTE等高级变体侧重于在少数类别最容易被错误分类的区域生成样本。
虽然有效,但合成样本生成并非没有潜在风险。如果不谨慎使用,它可能会引入噪声或创建不切实际的样本。重要的是要验证合成样本在你的问题领域中是否合理。
总结
处理不平衡数据是许多机器学习工作流程中的关键一步。在本文中,我们探讨了五种不同的方法:重采样方法、集成策略、类别加权、正确的评估指标以及生成人工样本。
请记住,正如机器学习中的所有事物一样,对于不平衡数据问题,并没有万能的解决方案。除了在你的项目中尝试各种不同的方法来解决这个问题之外,尝试将这些不同的方法混合使用,并尝试不同的可能配置,也是值得的。最佳方法将取决于手头的数据集、业务问题和特定问题的正式评估指标。
在你的机器学习项目中开发处理不平衡数据集的工具,只是你准备创建最有效的机器学习模型的又一种方式。
这篇博客文章非常有用且具有启发性。我要感谢你分享这些信息。我也有一个包含许多有用信息的网站。
你好 vcube……我们非常感谢你的反馈和支持!