我正在使用 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)
问题来了。我做了两个测试:
- 如果我对次要类别进行上采样,然后将我的数据集分成两组,一组用于训练,一组用于测试...准确度为:
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
非常好的结果。
- 如果我只对训练数据进行上采样,而将原始数据留作测试,则结果为:
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)使用测试集得到预测;最终预测将是分类器所有预测的多数投票结果。
要获得稳健的指标,请使用不同的初始拆分测试/训练执行不同的迭代。
关于python - 上采样不平衡数据集的小类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53218341/