今天给大家分享机器学习中的一个关键概念,类别不平衡。
类别不平衡指的是在分类问题中,不同类别的数据样本数量相差悬殊的情况。
在机器学习和深度学习的应用中,类别不平衡是一个常见的问题,尤其是在一些实际场景中,某些类别的数据相对较少,而其他类别的数据较多。例如,在医疗诊断中,患病的样本可能远远少于健康的样本,或者在欺诈检测中,欺诈交易的数量通常少于正常交易。
类别不平衡的问题会导致分类器在训练过程中倾向于预测数量较多的类别,而忽视数量较少的类别,进而影响分类结果的准确性和泛化能力。
类别不平衡的影响
- 模型偏向多数类
大多数机器学习算法(如逻辑回归、决策树、SVM等)往往会倾向于预测样本数目较多的类别,因为这可以最小化整体的错误率。
这样,模型可能会忽略少数类的样本,从而影响模型的泛化能力和对少数类的识别能力。 - 评价指标失真
在类别不平衡的数据集上,准确率(accuracy)通常不是一个有效的评估指标。即使模型完全忽略少数类,仍然可能获得较高的准确率(因为多数类的预测正确率较高)。因此,需要使用其他评价指标(如精确率、召回率、F1值、ROC-AUC等)来全面评估模型性能。 - 忽略少数类
对于一些特定任务,少数类可能非常重要,例如在疾病诊断、欺诈检测等场景中,少数类(如病人或欺诈交易)通常是更为关注的对象。忽略少数类会导致任务无法实现预期效果。
处理类别不平衡的常见方法
过采样
过采样是通过增加少数类样本的数量,使得少数类和多数类的样本数量达到平衡。
常用的过采样方法有以下几种:
随机过采样
通过简单地复制少数类样本,来增加少数类的数量。
优缺点
- 优点:实现简单,能快速增加少数类样本。
- 缺点:复制样本可能导致过拟合,因为模型可能会多次看到相同的样本,无法学到新知识。
from imblearn.over_sampling import RandomOverSampler
from sklearn.datasets import make_classification
from collections import Counter
# 创建一个不平衡的数据集
X, y = make_classification(n_samples=1000, n_features=20, n_classes=2,
weights=[0.1, 0.9], random_state=42)
print(f"原始数据集的类别分布: {Counter(y)}")
# 使用随机过采样进行数据平衡
ros = RandomOverSampler(random_state=42)
X_resampled, y_resampled = ros.fit_resample(X, y)
print(f"过采样后的类别分布: {Counter(y_resampled)}")
SMOTE
SMOTE 是最常用的过采样技术,它通过在少数类样本之间进行插值,生成新的合成样本。
原理
SMOTE 通过在特征空间中选择一个少数类样本及其最近邻样本,然后在它们之间进行插值来创建新的样本。
这些新合成的样本是对现有样本的一种变换,能够增加少数类的多样性。
- 随机选择一个少数类样本。
- 寻找其 k 个最近邻居。
- 通过在选定的实例和随机选择的邻居之间进行插值来生成合成实例。
优缺点
- 优点:通过合成样本,增强了数据的多样性,并且减少了过拟合的风险。
- 缺点:生成的合成样本可能不具有代表性,尤其在特征空间复杂时。
from imblearn.over_sampling import SMOTE
from sklearn.datasets import make_classification
from collections import Counter
# 创建一个不平衡的数据集
X, y = make_classification(n_samples=1000, n_features=20, n_classes=2,
weights=[0.1, 0.9], random_state=42)
print(f"原始数据集的类别分布: {Counter(y)}")
# 使用 SMOTE 进行数据平衡
smote = SMOTE(random_state=42)
X_resampled, y_resampled = smote.fit_resample(X, y)
print(f"SMOTE过采样后的类别分布: {Counter(y_resampled)}")
ADASYN
ADASYN 是对 SMOTE 的改进,旨在通过更多地生成那些分类器难以区分的少数类样本来增强数据集。
它的基本思想是:在那些靠近决策边界的少数类样本生成更多的合成样本,减少生成容易分类的样本。
优点
比 SMOTE 更加关注决策边界附近的难分类样本,可以提升模型在这些区域的表现。
from imblearn.over_sampling import ADASYN
from sklearn.datasets import make_classification
from collections import Counter
# 创建一个不平衡的数据集
X, y = make_classification(n_samples=1000, n_features=20, n_classes=2,
weights=[0.1, 0.9], random_state=42)
print(f"原始数据集的类别分布: {Counter(y)}")
# 使用 ADASYN 进行数据平衡
adasyn = ADASYN(random_state=42)
X_resampled, y_resampled = adasyn.fit_resample(X, y)
print(f"ADASYN过采样后的类别分布: {Counter(y_resampled)}")
欠采样
欠采样是通过减少多数类样本的数量,来平衡类别之间的样本比例。
常见的欠采样方法有:
随机欠采样
通过随机删除多数类样本,来减少多数类样本的数量。
优缺点
优点:能够显著减少训练数据的规模,降低计算开销。
缺点:丢失了大量的多数类信息,可能导致欠拟合,特别是在多数类样本本身数量庞大的情况下。
from imblearn.under_sampling import RandomUnderSampler
from sklearn.datasets import make_classification
from collections import Counter
# 创建一个不平衡的数据集
X, y = make_classification(n_samples=1000, n_features=20, n_classes=2,
weights=[0.1, 0.9], random_state=42)
print(f"原始数据集的类别分布: {Counter(y)}")
# 使用随机欠采样进行数据平衡
rus = RandomUnderSampler(random_state=42)
X_resampled, y_resampled = rus.fit_resample(X, y)
print(f"欠采样后的类别分布: {Counter(y_resampled)}")
Tomek Links
Tomek Links 是一种欠采样方法,通过识别边界上的实例对(即少数类样本和多数类样本非常接近的样本对),并删除那些多数类样本。这有助于清除数据集中的噪声,并提升分类效果。
优缺点
- 优点:有助于消除噪声样本,并清晰定义决策边界。
- 缺点:可能会删除一些重要的多数类样本,影响数据的完整性。
from imblearn.under_sampling import TomekLinks
from sklearn.datasets import make_classification
from collections import Counter
# 创建一个不平衡的数据集
X, y = make_classification(n_samples=1000, n_features=20, n_classes=2,
weights=[0.1, 0.9], random_state=42)
print(f"原始数据集的类别分布: {Counter(y)}")
# 使用 Tomek Links 进行欠采样
tomek = TomekLinks()
X_resampled, y_resampled = tomek.fit_resample(X, y)
print(f"Tomek Links处理后的类别分布: {Counter(y_resampled)}")