Skip to main content
 首页 » 编程设计

python之上采样不平衡数据集的小类

2025年05月04日14lyj

我正在使用 scikit-learn 对我的数据进行分类,目前我正在运行一个简单的 DecisionTree 分类器。 我有三个类(class)有很大的不平衡问题。类是 0,1 和 2。小类是 1 和 2。

让您了解类的样本数量:

0 = 25.000 samples 
1 = 15/20 less or more 
2 = 15/20 less or more 

所以次要类大约占数据集的 0.06%。 我正在遵循的解决不平衡问题的方法是小类的 UPSAMPLING。代码:

from sklearn.utils import resample, 
resample(data, replace=True, n_samples=len_major_class, random_state=1234) 

问题来了。我做了两个测试:

  1. 如果我对次要类别进行上采样,然后将我的数据集分成两组,一组用于训练,一组用于测试...准确度为:
             precision    recall  f1-score   support 
 
          0       1.00      1.00      1.00     20570 
          1       1.00      1.00      1.00     20533 
          2       1.00      1.00      1.00     20439 
 
avg / total       1.00      1.00      1.00     61542 

非常好的结果。

  1. 如果我只对训练数据进行上采样,而将原始数据留作测试,则结果为:
             precision    recall  f1-score   support 
 
          0       1.00      1.00      1.00     20570 
          1       0.00      0.00      0.00        15 
          2       0.00      0.00      0.00        16 
 
avg / total       1.00      1.00      1.00     20601 

如您所见,全局精度很高,但 1 类和 2 类的精度为零。

我正在以这种方式创建分类器:

DecisionTreeClassifier(max_depth=20, max_features=0.4, random_state=1234, criterion='entropy') 

我也尝试过添加 class_weight 和 balanced 值,但没有任何区别。

我应该只对训练数据进行上采样,为什么我会遇到这个奇怪的问题?

请您参考如下方法:

当您在拆分之前进行重新采样时,您获得该行为的事实是很正常的;你在你的数据中引起了偏见。

如果对数据进行过采样然后拆分,则测试中的少数样本将不再独立于训练集中的样本,因为它们是一起生成的。在您的情况下,它们是训练集中样本的精确副本。您的准确率为 100%,因为分类器正在对训练中已经出现过的样本进行分类。

由于您的问题非常不平衡,我建议使用一组分类器来处理它。 1)将你的数据集拆分成训练集和测试集。给定数据集的大小,您可以从少数类别中抽取 1-2 个样本进行测试,而将另一个样本留作训练。 2) 从训练中生成 N 个数据集,其中包含少数类的所有剩余样本和多数类的欠样本(我会说 2*少数类样本数)。 3)对于获得的每个数据集,您都训练一个模型。 4)使用测试集得到预测;最终预测将是分类器所有预测的多数投票结果。

要获得稳健的指标,请使用不同的初始拆分测试/训练执行不同的迭代。