一、SMOTE过采样
1.1 问题
在实际业务中,样本不均衡(即正负样本比例严重失衡)是一种常见的问题。这种情况下,传统的机器学习算法可能会倾向于偏向占主导地位的类别,从而导致模型性能下降。
1.2 SMOTE方法
为了解决这个问题,一种常用的方法是过采样,其中SMOTE(SyntheticMinority Over-sampling Technique)是一种被广泛应用的技术。
SMOTE过采样方法的主要作用是通过合成少数类样本来增加其在数据集中的数量,以达到样本平衡。这对于改善模型的训练效果至关重要。通过SMOTE过采样,可以使得模型更好地学习到少数类别的特征,从而提高模型的泛化能力和准确性。此外,SMOTE过采样方法还可以减少模型的过拟合倾向,提高模型的稳健性(Robustness)。
1.3 SMOTE原理
SMOTE过采样方法基于样本的特征空间,通过对少数类样本进行插值来生成合成样本。其主要步骤如下:
- 对于每一个少数类样本,计算其与所有其他少数类样本之间的距离,并找到其K个最近邻居。
- 从这K个最近邻居中随机选择一个样本,并计算该样本与当前样本的差异。
- 根据差异比例,生成一个新的合成样本,该样本位于两个样本之间的连线上。
- 重复上述步骤,生成指定数量的合成样本。
1.4 与其他采样方法对比
方法 | 原理 | 优点 | 缺点 |
---|---|---|---|
随机过采样 | 简单复制少数类样本来平衡数据集 | 简单易实施,适用于小型数据集 | 容易导致过拟合问题,复制的样本可能会引入噪声。对于较大的数据集,会导致内存占用过高 |
自适应综合过采样 | 根据样本密度分布来调整合成样本的数量 | 能够更好地处理样本密度不均衡的情况,适用于非线性问题。 | 计算成本较高,对于高维数据集效果可能不佳。 |
SMOTE | 通过插值生成合成样本 | 在处理数据不平衡问题时表现良好,能够有效增加少数类样本。基于合成样本的插值方法能够在特征空间中扩展少数类样本,有助于模型学习到更多的特征信息。 | 对于噪声和离群点敏感;无法处理样本重叠问题;处理多类别不平衡问题的能力有限 |
二、SMOTE代码实现
2.1 pytorch实现SMOTE
1、安装 imbalanced-learn 库:
pip install -U imbalanced-learn
2、导入必要的库和模块:
import torch
import torch.nn as nn
from torch.utils.data import DataLoader, TensorDataset
from imblearn.over_sampling import SMOTE
准备原始数据集: 假设你有一个包含特征和标签的PyTorch张量 X 和 y,其中 X 的形状是 (样本数, 特征数),y 的形状是 (样本数, )。
使用 SMOTE 进行过采样:
# 将 PyTorch 张量转换为 NumPy 数组
X_np = X.numpy()
y_np = y.numpy()# 使用 SMOTE 进行过采样
smote = SMOTE(sampling_strategy='auto', random_state=42)
X_resampled, y_resampled = smote.fit_resample(X_np, y_np)# 将 NumPy 数组转换为 PyTorch 张量
X_resampled = torch.from_numpy(X_resampled)
y_resampled = torch.from_numpy(y_resampled)
注意:
sampling_strategy=‘auto’ 表示自动计算过采样的目标类别比例。
random_state 是一个随机种子,用于确保可重复性。
将过采样后的数据转回 PyTorch 张量:
2.2 在XGBoost中使用SMOTE
1、安装 imbalanced-learn 库:
pip install -U imbalanced-learn
2、导入必要的库和模块:
import xgboost as xgb
from imblearn.over_sampling import SMOTE
准备原始数据集: 假设你有一个包含特征和标签的XGBoost的DMatrix对象 dtrain。
3、使用 SMOTE 进行过采样:
# 获取原始数据集的特征矩阵和标签
X, y = dtrain.get_x(), dtrain.get_label()# 使用 SMOTE 进行过采样
smote = SMOTE(sampling_strategy='auto', random_state=42)
X_resampled, y_resampled = smote.fit_resample(X, y)# 将 NumPy 数组转换为 XGBoost 的 DMatrix 对象
dtrain_resampled = xgb.DMatrix(X_resampled, label=y_resampled)
4、定义并训练XGBoost模型:
# 定义参数
params = {'objective': 'binary:logistic','eval_metric': ['logloss', 'auc'],'eta': 0.05,'max_depth': 9,# 其他参数...
}# 训练模型
model = xgb.train(params, dtrain_resampled, num_boost_round=200, early_stopping_rounds=10)