函数作用
这个函数的核心作用是解决分类问题中的数据不平衡(Class Imbalance)问题。
什么是数据不平衡?
在分类任务中,当不同类别的样本数量相差悬殊时,就是数据不平衡。例如:
python
# 欺诈检测场景
正常交易: 9900条 (99%)
欺诈交易: 100条 (1%) ← 少数类(我们更关心)
# 疾病诊断场景
健康人群: 9500条 (95%)
患病者: 500条 (5%) ← 少数类(我们更关心)
这个函数具体做了什么?
1. 检测数据不平衡
-
分析训练集中各个类别的样本数量
-
识别出哪些是少数类,哪些是多数类
2. 应用SMOTE算法生成新样本
python
# 原始数据:少数类只有100个样本
少数类样本: [样本1, 样本2, ..., 样本100]
# SMOTE的工作原理:
# 1. 在少数类样本之间进行插值
# 2. 生成新的合成样本
新样本1 = 样本1 + random(0,1) * (样本2 - 样本1)
新样本2 = 样本3 + random(0,1) * (样本4 - 样本3)
# ... 直到少数类数量与多数类平衡
# 结果:少数类从100个增加到9900个
3. 返回平衡后的数据集
python
# 处理前
X_train: 10000个样本(9900正常 + 100欺诈)
y_train: [0,0,0,...,1,1,1] # 严重不平衡
# 处理后
X_resampled: 19800个样本(9900正常 + 9900合成欺诈)
y_resampled: [0,0,0,...,1,1,1] # 平衡了!
为什么需要这个函数?
如果不处理数据不平衡:
python
# 假设用不平衡数据训练模型
from sklearn.ensemble import RandomForestClassifier
model = RandomForestClassifier()
model.fit(X_train, y_train) # 其中99%是正常样本
# 模型会学到:只要预测为"正常",准确率就有99%
# 结果:所有欺诈样本都会被误判为正常
# 准确率99%,但一个欺诈都检测不出来!
使用这个函数后:
python
# 平衡后的数据训练
X_balanced, y_balanced = fix_imbalance_classification(X_train, y_train)
model.fit(X_balanced, y_balanced)
# 模型现在能正确识别欺诈样本
# 真正关注的重点(欺诈检测)得到提
import numpy as np
from sklearn.preprocessing import StandardScaler
def fix_imbalance_classification(X_train, y_train, method='smote',
random_state=42, scale=False, **kwargs):
"""
处理分类任务中的数据不平衡问题
Parameters:
-----------
X_train : array-like, shape (n_samples, n_features)
训练特征数据
y_train : array-like, shape (n_samples,)
训练标签数据
method : str, default='smote'
重采样方法: 'smote', 'adasyn', 'smote_tomek', 'smote_enn'
random_state : int, default=42
随机种子
scale : bool, default=False
是否在重采样前进行标准化(SMOTE对尺度敏感)
**kwargs :
传递给重采样器的额外参数
Returns:
--------
X_resampled, y_resampled : 重采样后的数据
"""
# 输入验证
if X_train is None or y_train is None:
raise ValueError("X_train and y_train cannot be None")
if len(X_train) != len(y_train):
raise ValueError("X_train and y_train must have same length")
if len(np.unique(y_train)) < 2:
raise ValueError("Need at least 2 classes for oversampling")
# 可选的数据标准化
if scale:
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
# 选择重采样方法
try:
if method == 'smote':
from imblearn.over_sampling import SMOTE
resampler = SMOTE(random_state=random_state, **kwargs)
elif method == 'adasyn':
from imblearn.over_sampling import ADASYN
resampler = ADASYN(random_state=random_state, **kwargs)
elif method == 'smote_tomek':
from imblearn.combine import SMOTETomek
resampler = SMOTETomek(random_state=random_state, **kwargs)
elif method == 'smote_enn':
from imblearn.combine import SMOTEENN
resampler = SMOTEENN(random_state=random_state, **kwargs)
else:
supported_methods = ['smote', 'adasyn', 'smote_tomek', 'smote_enn']
raise ValueError(f"method must be one of {supported_methods}")
except ImportError:
raise ImportError("Please install imbalanced-learn: pip install imbalanced-learn")
# 执行重采样
X_resampled, y_resampled = resampler.fit_resample(X_train, y_train)
# 如果进行了标准化,需要逆转换(可选)
# 注意:通常保留标准化后的数据用于模型训练
return X_resampled, y_resampled
这个函数让模型不再"忽视"少数类,从而在真实世界中(如欺诈检测、疾病诊断)做出更准确的判断。