非均衡分类实战:过采样+代价敏感学习全攻略
引言
在金融风控等实际场景中,我们经常会遇到正负样本比例严重失衡的情况(比如1:100)。这种情况下,普通分类器往往会直接"躺平"——把所有样本都预测为多数类(负例),虽然准确率看起来很高,但实际上完全失去了识别风险的能力。
本文将带你用Python实战解决这个难题,重点介绍两种核心方法: -SMOTE过采样:通过智能生成少数类样本来平衡数据 -代价敏感学习:让模型更"在意"错判少数类的代价
无需复杂理论,跟着操作就能获得实际可用的解决方案。学完后你将能够: - 处理1:100甚至更极端的样本不均衡 - 选择最适合业务场景的评估指标 - 调整关键参数避免过拟合
1. 环境准备
首先确保你的Python环境已安装以下库:
pip install imbalanced-learn scikit-learn pandas numpy关键工具说明: -imbalanced-learn:提供SMOTE等过采样算法 -scikit-learn:包含分类器和评估指标 -pandas:数据处理必备
💡 提示
如果你使用CSDN的GPU环境,这些库通常已经预装。可以直接选择"机器学习"类镜像快速开始。
2. 数据加载与探索
假设我们有一个信用卡欺诈检测数据集,正例(欺诈)占比仅1%:
import pandas as pd from sklearn.model_selection import train_test_split # 加载数据 data = pd.read_csv('creditcard.csv') X = data.drop('Class', axis=1) y = data['Class'] # 查看类别分布 print(y.value_counts()) # 输出示例: # 0 284315 # 1 4923. 基础解决方案对比
3.1 普通逻辑回归的问题
先看看普通分类器在不处理不均衡时的表现:
from sklearn.linear_model import LogisticRegression from sklearn.metrics import classification_report # 划分训练测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3) # 训练普通模型 model = LogisticRegression() model.fit(X_train, y_train) # 评估 print(classification_report(y_test, y_pred))典型输出:
precision recall f1-score support 0 1.00 1.00 1.00 85307 1 0.00 0.00 0.00 148模型把所有样本都预测为0(正常交易),完全无法识别欺诈!
3.2 解决方案一:SMOTE过采样
SMOTE通过生成合成样本来平衡数据集:
from imblearn.over_sampling import SMOTE # 应用SMOTE smote = SMOTE(random_state=42) X_res, y_res = smote.fit_resample(X_train, y_train) # 查看平衡后的分布 print(pd.Series(y_res).value_counts()) # 输出示例: # 0 199020 # 1 199020现在两类样本完全平衡了。重新训练模型:
model.fit(X_res, y_res) y_pred = model.predict(X_test) print(classification_report(y_test, y_pred))你会看到recall(召回率)明显提升,模型开始能识别部分欺诈交易了。
3.3 解决方案二:代价敏感学习
另一种思路是让模型更"在意"错判少数类的代价:
# 设置类别权重 model = LogisticRegression(class_weight={0:1, 1:100}) # 把少数类错误代价设为100倍 model.fit(X_train, y_train) y_pred = model.predict(X_test) print(classification_report(y_test, y_pred))4. 进阶技巧组合使用
4.1 SMOTE + 代价敏感学习
将两种方法结合往往能获得更好效果:
smote = SMOTE(random_state=42) X_res, y_res = smote.fit_resample(X_train, y_train) model = LogisticRegression(class_weight={0:1, 1:10}) # 适当降低权重 model.fit(X_res, y_res)4.2 使用Focal Loss(针对神经网络)
如果你使用深度学习模型,可以尝试Focal Loss:
import tensorflow as tf def focal_loss(gamma=2.0, alpha=0.25): def focal_loss_fn(y_true, y_pred): # 实现细节省略 return loss return focal_loss_fn model.compile(optimizer='adam', loss=focal_loss())5. 评估指标选择
在不均衡分类中,准确率完全不可靠!应该关注: -召回率(Recall):捕获了多少真正的少数类 -精确率(Precision):预测的少数类中有多少是真的 -F1分数:两者的调和平均 -AUC-ROC:综合评估模型区分能力
from sklearn.metrics import roc_auc_score print("AUC:", roc_auc_score(y_test, y_pred))6. 常见问题与调优
6.1 SMOTE过拟合怎么办?
- 使用
SMOTEENN(SMOTE+编辑最近邻)组合 - 调整
k_neighbors参数(默认5) - 在交叉验证中应用SMOTE,而不是全局应用
6.2 如何确定类别权重?
- 使用
class_weight='balanced'自动计算 - 通过网格搜索寻找最优权重
- 根据业务成本确定(如欺诈漏判的成本/误判的成本)
6.3 样本极度不平衡(1:1000+)?
- 先降采样多数类到1:100
- 再应用SMOTE平衡到1:1
- 考虑分层抽样保持分布
总结
- 核心方法:SMOTE过采样和代价敏感学习是处理不均衡分类的两大法宝
- 评估指标:放弃准确率,关注Recall、Precision、F1和AUC
- 组合使用:SMOTE+代价敏感通常效果最佳
- 参数调优:k_neighbors和class_weight是关键调节点
- 业务适配:根据实际成本调整权重,没有放之四海皆准的参数
现在就去试试这些方法吧!在实际风控项目中,这些技巧能让你的模型从"装死"变成"火眼金睛"。
💡获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。