第一部分:不均衡学习
1. 引言
定义与重要性
- 不均衡数据集:指数据集中不同类别的数据数量差异很大,通常是正负样本比例严重失衡。例如,在医疗诊断中,患病患者(正样本)远少于健康患者(负样本)。
- 重要性:在许多实际应用中,如医疗诊断、欺诈检测等,少数类样本往往代表重要的情况。忽略少数类可能导致严重后果,例如未能检测出欺诈交易。
2. 不均衡数据处理方法
重采样方法
欠采样(Under-sampling)
- 定义:通过减少多数类样本的数量来平衡数据集。
- 优点:减少数据量,训练速度快。
- 缺点:可能丢失多数类的重要信息。
Python代码示例:
from imblearn.under_sampling import RandomUnderSampler
from sklearn.datasets import make_classification
# 生成一个不均衡数据集
X, y = make_classification(n_samples=1000, n_features=20, n_classes=2, weights=[0.9, 0.1], random_state=42)
# 欠采样
rus = RandomUnderSampler(random_state=42)
X_res, y_res = rus.fit_resample(X, y)
print("原始数据集类分布:", dict(zip(*np.unique(y, return_counts=True))))
print("欠采样后类分布:", dict(zip(*np.unique(y_res, return_counts=True))))
运行结果解释:
- 原始数据集中,正负样本比例可能为90:10。
- 经过欠采样后,正负样本比例接近1:1,但可能丢失了多数类的重要信息。
过采样(Over-sampling)
- 定义:通过增加少数类样本的数量来平衡数据集。
- 优点:保留所有多数类信息。
- 缺点:可能导致过拟合,即模型过于拟合训练数据,在新数据上表现不佳。
Python代码示例:
from imblearn.over_sampling import RandomOverSampler
# 过采样
ros = RandomOverSampler(random_state=42)
X_res, y_res = ros.fit_resample(X, y)
print("原始数据集类分布:", dict(zip(*np.unique(y, return_counts=True))))
print("过采样后类分布:", dict(zip(*np.unique(y_res, return_counts=True))))
运行结果解释:
- 原始数据集中,正负样本比例可能为90:10。
- 经过过采样后,正负样本比例接近1:1,但可能导致模型过拟合。
SMOTE(Synthetic Minority Over-sampling Technique)
- 定义:通过生成少数类的合成样本来平衡数据集。
- 算法原理:
- 对于每个少数类样本,随机选择k个最近邻样本,生成新样本。
- 公式:新样本 xnew=xi+λ⋅(xnn−xi)x_{\text{new}} = x_i + \lambda \cdot (x_{nn} - x_i)xnew=xi+λ⋅(xnn−xi)
- 其中,xix_ixi 是少数类样本,xnnx_{nn}xnn 是k个最近邻样本之一,λ\lambdaλ 是0到1之间的随机数。
Python代码示例:
from imblearn.over_sampling import SMOTE
# 使用SMOTE
smote = SMOTE(random_state=42)
X_res, y_res = smote.fit_resample(X, y)
print("原始数据集类分布:", dict(zip(*np.unique(y, return_counts=True))))
print("SMOTE后类分布:", dict(zip(*np.unique(y_res, return_counts=True))))
运行结果解释:
- 原始数据集中,正负样本比例可能为90:10。
- 经过SMOTE后,正负样本比例接近1:1,并且生成的新样本更具代表性,有助于减轻过拟合。
数据增强技术
- 定义:通过对现有数据进行变换(如旋转、缩放等)增加样本数量,主要用于图像数据。
- 优点:适用于图像数据,增强模型的泛化能力。
- 缺点:需要特定领域知识。
Python代码示例:
from keras.preprocessing.image import ImageDataGenerator
import numpy as np
# 假设我们有一个图像数据集
datagen = ImageDataGenerator(rotation_range=40, width_shift_range=0.2, height_shift_range=0.2, zoom_range=0.2)
# 假设X_train包含我们的图像数据
X_train_augmented = datagen.flow(X_train, batch_size