Python 上采样不平衡数据集&x27;小班

Python 上采样不平衡数据集&x27;小班,python,machine-learning,scikit-learn,Python,Machine Learning,Scikit Learn,我正在使用scikit学习对数据进行分类,目前我正在运行一个简单的决策树分类器。 我有三节课有一个很大的不平衡问题。这些类是0、1和2。辅修班是1班和2班 要让您了解这些类的样本数量,请执行以下操作: 0 = 25.000 samples 1 = 15/20 less or more 2 = 15/20 less or more 因此,次要类约占数据集的0.06%。 我所采用的解决不平衡问题的方法是对次要类进行上采样。代码: from sklearn.utils import resample

我正在使用scikit学习对数据进行分类,目前我正在运行一个简单的决策树分类器。 我有三节课有一个很大的不平衡问题。这些类是0、1和2。辅修班是1班和2班

要让您了解这些类的样本数量,请执行以下操作:

0 = 25.000 samples
1 = 15/20 less or more
2 = 15/20 less or more
因此,次要类约占数据集的0.06%。 我所采用的解决不平衡问题的方法是对次要类进行上采样。代码:

from sklearn.utils import resample,
resample(data, replace=True, n_samples=len_major_class, random_state=1234)
现在问题来了。我做了两个测试:

  • 如果我对小班进行抽样,然后将数据集分为两组,一组用于培训,另一组用于测试。。。准确度为:
  • 效果非常好

  • 如果我只对训练数据进行上采样,并保留原始数据进行测试,结果是:
  • 如您所见,全局精度很高,但类别1和类别2的精度为

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

    DecisionTreeClassifier(max_depth=20, max_features=0.4, random_state=1234, criterion='entropy')
    
    我还尝试添加
    class\u权重
    平衡值,但没有任何区别


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

    上采样后不应该分割数据集。您可以在训练数据中进行上采样


    基本上,您正在将测试数据泄漏到训练数据中

    上采样后不应分割数据集。您可以在训练数据中进行上采样


    基本上,您正在将测试数据泄漏到训练数据中

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

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

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


    为了让稳健的指标通过不同的初始分割测试/训练执行不同的迭代

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

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

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


    为了让稳健的指标通过不同的初始分割测试/训练执行不同的迭代

    我有一个函数,可以对每个类的数据集进行重新采样,以获得相同数量的实例

    from sklearn.utils import resample
    import pandas as pd
    
    def make_resample(_df, column):
    
      dfs_r = {}
      dfs_c = {}
      bigger = 0
      ignore = ""
      for c in _df[column].unique():
        dfs_c[c] = _df[df[column] == c]
        if dfs_c[c].shape[0] > bigger:
          bigger = dfs_c[c].shape[0]
          ignore = c
    
      for c in dfs_c:
        if c == ignore:
          continue
        dfs_r[c] = resample(dfs_c[c], 
                            replace=True,
                            n_samples=bigger - dfs_c[c].shape[0],
                            random_state=0)
      return pd.concat([dfs_r[c] for c in dfs_r] + [_df])
    

    我有一个函数,它为每个类重新采样数据集,以获得相同数量的实例

    from sklearn.utils import resample
    import pandas as pd
    
    def make_resample(_df, column):
    
      dfs_r = {}
      dfs_c = {}
      bigger = 0
      ignore = ""
      for c in _df[column].unique():
        dfs_c[c] = _df[df[column] == c]
        if dfs_c[c].shape[0] > bigger:
          bigger = dfs_c[c].shape[0]
          ignore = c
    
      for c in dfs_c:
        if c == ignore:
          continue
        dfs_r[c] = resample(dfs_c[c], 
                            replace=True,
                            n_samples=bigger - dfs_c[c].shape[0],
                            random_state=0)
      return pd.concat([dfs_r[c] for c in dfs_r] + [_df])
    
    from sklearn.utils import resample
    import pandas as pd
    
    def make_resample(_df, column):
    
      dfs_r = {}
      dfs_c = {}
      bigger = 0
      ignore = ""
      for c in _df[column].unique():
        dfs_c[c] = _df[df[column] == c]
        if dfs_c[c].shape[0] > bigger:
          bigger = dfs_c[c].shape[0]
          ignore = c
    
      for c in dfs_c:
        if c == ignore:
          continue
        dfs_r[c] = resample(dfs_c[c], 
                            replace=True,
                            n_samples=bigger - dfs_c[c].shape[0],
                            random_state=0)
      return pd.concat([dfs_r[c] for c in dfs_r] + [_df])