类别不平衡问题
类别不平衡问题(Class Imbalance Problem)是机器学习里非常经典且常见的一种情况。简单来说,就是在你用来训练模型的数据集里,不同类别的样本数量相差悬殊。
比如,在检测信用卡欺诈时,正常的交易可能有 99.9%,而欺诈交易只有 0.1%。如果模型“偷懒”把所有交易都预测为正常,它的准确率也能达到 99.9%,但这显然是个完全没用的模型。
面对这个问题,我们可以从数据、算法和评估指标这三个维度来“对症下药”:
📊 数据层面(最直接的方法)
核心思路是调整训练数据的分布,让正负样本的数量尽量接近。
- 过采样(Oversampling):增加少数类样本的数量。
- 随机过采样:简单地随机复制少数类样本。缺点是容易导致过拟合。
- SMOTE(合成少数类过采样技术):这是一个很经典的方法。它不是简单复制,而是通过分析少数类样本的特征,在它们之间“合成”出新的、类似的样本。
- 欠采样(Undersampling):减少多数类样本的数量。
- 随机欠采样:随机丢弃一些多数类样本。缺点是可能会丢失重要信息。
- Tomek Links / 聚类欠采样:更有策略地去除那些容易被混淆的多数类样本,保留更有代表性的。
- 数据增强(Data Augmentation):尤其在图像领域,可以通过旋转、裁剪、调整颜色等方式,人为创造出更多的少数类样本。
⚙️ 算法层面(让模型更“重视”少数类)
如果不想改动原始数据,可以通过调整算法的训练机制来解决。
- 调整类别权重(Class Weights):这是最常用且高效的方法。在训练时,给少数类样本赋予更高的“权重”,给多数类赋予较低的权重。这样,模型如果在少数类上犯错,受到的“惩罚”会更大,从而迫使模型更关注少数类。大多数主流框架(如 Scikit-learn, PyTorch, TensorFlow)都支持在损失函数中设置
class_weight='balanced'。 - 使用集成学习(Ensemble Learning):
- Bagging:如 Balanced Random Forest,它在构建每棵树时都对数据进行欠采样,保证每棵树面对的数据都是平衡的。
- Boosting:如 AdaBoost、XGBoost、LightGBM。这类算法天生对不平衡数据有一定的抵抗力,因为它们会不断关注之前被预测错误的样本(通常包含少数类)。
📏 评估指标层面(拒绝被“准确率”欺骗)
当数据不平衡时,准确率(Accuracy)往往是最具误导性的指标。你需要换用更客观的尺子来衡量模型:
- 混淆矩阵(Confusion Matrix):直观地看模型到底把多少正样本预测对了,多少负样本预测错了。
- 精确率(Precision)与 召回率(Recall):
- 如果更看重“抓得全不全”(比如癌症筛查),重点看召回率。
- 如果更看重“抓得准不准”(比如垃圾邮件拦截),重点看精确率。
- F1-Score:精确率和召回率的调和平均数,是一个综合指标。
- AUC-ROC 曲线:衡量模型在不同阈值下的分类能力,对类别不平衡不太敏感,是非常稳健的指标。
- PR 曲线(Precision-Recall Curve):在极度不平衡的数据集下,PR 曲线往往比 ROC 曲线更能反映真实情况。
💡 总结建议
在实际工作中,通常的解决路径是:
- 首先更换评估指标,不要只看准确率。
- 尝试在算法中设置
class_weight='balanced'(成本最低,效果往往不错)。 - 如果效果仍不理想,再尝试SMOTE等数据重采样方法。
