数据不平衡是 NLP 任务中常见的问题,指各类别的样本数量差异显著。这会导致模型偏向多数类,影响少数类的识别效果。以下是处理数据不平衡的多种方法。
问题分析
不平衡的类型
- 类别不平衡:某些类别样本远多于其他类别
- 长尾分布:少数类别样本极少
- 极端不平衡:正负样本比例超过 100:1
影响
- 模型偏向多数类
- 准确率指标误导
- 少数类召回率低
- 实际应用效果差
数据层面方法
1. 过采样(Oversampling)
随机过采样
- 随机复制少数类样本
- 简单易实现
- 可能导致过拟合
SMOTE(Synthetic Minority Over-sampling Technique)
- 合成新的少数类样本
- 在特征空间插值
- 适用于连续特征
ADASYN(Adaptive Synthetic Sampling)
- 自适应合成采样
- 根据学习难度生成样本
- 关注难分类样本
文本特定方法
- 同义词替换
- 回译(Back-translation)
- 文本增强(Text Augmentation)
- 上下文替换
2. 欠采样(Undersampling)
随机欠采样
- 随机删除多数类样本
- 可能丢失重要信息
- 适用于数据量大的情况
Tomek Links
- 移除边界附近的多数类样本
- 改善类别分离
- 结合其他方法使用
NearMiss
- 基于距离选择代表性样本
- 保留多数类中的关键样本
- 多种变体可选
聚类欠采样
- 对多数类聚类
- 每个簇保留代表性样本
- 保留数据分布
3. 混合采样
- 结合过采样和欠采样
- SMOTE + Tomek Links
- SMOTEENN
- 平衡数据分布
算法层面方法
1. 损失函数调整
类别加权(Class Weighting)
- 为少数类分配更高权重
- 反比于类别频率
- 公式:weight_i = N / (C × n_i)
Focal Loss
- 关注难分类样本
- 动态调整权重
- 公式:FL = -α(1 - p_t)^γ log(p_t)
代价敏感学习
- 不同类别不同误分类代价
- 基于业务需求设定
- 优化总体代价
2. 集成方法
Bagging
- Bootstrap Aggregating
- 每个基模型使用平衡采样
- 投票或平均
Boosting
- AdaBoost:调整样本权重
- XGBoost:支持类别权重
- LightGBM:处理不平衡数据
EasyEnsemble
- 对多数类多次欠采样
- 训练多个分类器
- 集成预测
BalanceCascade
- 级联集成学习
- 逐步移除正确分类的样本
- 提升少数类性能
3. 阈值调整
移动决策阈值
- 调整分类阈值
- 提高少数类召回率
- 基于验证集优化
概率校准
- Platt Scaling
- Isotonic Regression
- 改善概率估计
模型层面方法
1. 深度学习特定方法
采样策略
- Batch-level sampling
- 动态采样
- 困难样本挖掘
损失函数
- 加权交叉熵
- Dice Loss
- OHEM(Online Hard Example Mining)
架构设计
- 注意力机制
- 多任务学习
- 迁移学习
2. 预训练模型微调
类别平衡微调
- 调整学习率
- 使用类别权重
- 分层微调
Prompt Engineering
- 设计平衡的提示
- 少样本学习
- 链式思考
评估方法
1. 合适的评估指标
不依赖准确率
- 精确率(Precision)
- 召回率(Recall)
- F1 分数
- AUC-ROC
- AUC-PR(更适合不平衡)
混淆矩阵分析
- 查看各类别表现
- 识别错误模式
- 指导改进方向
2. 交叉验证策略
分层交叉验证
- 保持类别分布
- Stratified K-Fold
- 更可靠的评估
重复交叉验证
- 多次运行
- 减少方差
- 稳定结果
实践建议
1. 数据准备阶段
- 分析类别分布
- 识别不平衡程度
- 了解业务需求
2. 方法选择
- 数据量小:过采样
- 数据量大:欠采样
- 深度学习:损失函数调整
- 传统模型:集成方法
3. 组合策略
- 数据层面 + 算法层面
- 多种方法结合
- 实验验证效果
4. 监控和迭代
- 持续监控模型性能
- 收集反馈数据
- 迭代优化
常见场景和解决方案
1. 情感分析
- 正负样本不平衡
- 使用 Focal Loss
- 数据增强
2. 命名实体识别
- 实体类型不平衡
- 类别加权
- 采样策略
3. 文本分类
- 长尾类别
- 元学习
- Few-shot Learning
4. 垃圾邮件检测
- 正常邮件远多于垃圾邮件
- 异常检测方法
- 半监督学习
工具和库
Python 库
- imbalanced-learn:不平衡数据处理
- scikit-learn:采样和评估
- PyTorch:自定义损失函数
- TensorFlow:类别权重
预训练模型
- Hugging Face Transformers:微调策略
- Fairseq:序列到序列任务
- spaCy:工业级 NLP
最佳实践
1. 从简单开始
- 先尝试类别加权
- 再考虑数据采样
- 最后复杂方法
2. 验证集平衡
- 保持验证集分布
- 或创建平衡验证集
- 可靠评估
3. 业务对齐
- 理解业务目标
- 选择合适指标
- 优化关键性能
4. 持续改进
- 收集更多数据
- 主动学习
- 人机协同
案例研究
案例 1:情感分析
- 问题:负面评论仅占 5%
- 解决:SMOTE + Focal Loss
- 结果:F1 从 0.3 提升到 0.75
案例 2:医疗文本分类
- 问题:罕见疾病样本极少
- 解决:Few-shot Learning + 元学习
- 结果:罕见疾病召回率提升 40%
案例 3:垃圾邮件检测
- 问题:99% 正常邮件
- 解决:异常检测 + 阈值调整
- 结果:召回率 95%,精确率 98%