代码之家  ›  专栏  ›  技术社区  ›  Dail

上采样不平衡数据集的次要类

  •  1
  • Dail  · 技术社区  · 7 年前

    我正在使用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. 如果我对小班进行抽样,然后将数据集分为两组,一组用于培训,另一组用于测试。。。准确度为:
                 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 平衡的 价值,但没有区别。

    2 回复  |  直到 7 年前
        1
  •  6
  •   Roberto    7 年前

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

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

        2
  •  1
  •   Venkatachalam    7 年前

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

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

        3
  •  0
  •   E.G. Cortes    5 年前

    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])
    
    推荐文章