【问题标题】:How to perform under sampling in scikit learn?如何在 scikit learn 中进行欠采样?
【发布时间】:2015-05-26 01:47:13
【问题描述】:

我们有一个视网膜数据集,其中患病的眼睛信息占信息的 70%,而未患病的眼睛占剩余的 30%。我们想要一个数据集,其中患病和未患病的样本在数量上应该相等。是否有任何可用的功能可以帮助我们做同样的事情?

【问题讨论】:

    标签: python python-2.7 dataset scikit-learn sampling


    【解决方案1】:

    您可以使用np.random.choice 进行如前所述的简单欠采样,但问题可能是您的某些随机样本非常相似,因此会歪曲数据集。

    更好的选择是使用imbalanced-learn 包,它有多个用于平衡数据集的选项。可以在here 找到一个很好的教程和描述。

    该软件包列出了一些很好的欠采样选项(来自他们的 github):

    • 带放回的随机多数欠采样
    • 提取多数-少数 Tomek 链接
    • 使用聚类质心进行欠采样
    • NearMiss-(1 & 2 & 3)
    • 压缩最近邻
    • 单面选择
    • 小区清洁规定
    • 编辑最近的邻居
    • 实例硬度阈值
    • 重复编辑的最近邻居
    • AllKNN

    【讨论】:

      【解决方案2】:

      我会选择使用Pandas DataFramenumpy.random.choice 来执行此操作。通过这种方式,很容易进行随机抽样以产生相同大小的数据集。一个例子:

      import pandas as pd
      import numpy as np
      
      data = pd.DataFrame(np.random.randn(7, 4))
      data['Healthy'] = [1, 1, 0, 0, 1, 1, 1]
      

      此数据包含两个非健康样本和五个健康样本。从健康人群中随机抽取两个样本:

      healthy_indices = data[data.Healthy == 1].index
      random_indices = np.random.choice(healthy_indices, 2, replace=False)
      healthy_sample = data.loc[random_indices]
      

      要自动选择与非健康组相同大小的子样本,您可以这样做:

      sample_size = sum(data.Healthy == 0)  # Equivalent to len(data[data.Healthy == 0])
      random_indices = np.random.choice(healthy_indices, sample_size, replace=False)
      

      【讨论】:

      • 如果我错了请纠正我,但是在选择健康组之后再选择与非健康组相同大小的子样本,不会是:` not_healthy = df[df.Healthy == 0].index random_indices = np.random.choice(not_healthy, sum(data['healthy']), replace=False) renew_sample = data.loc[random_indices]`
      【解决方案3】:

      作为一种变体,您可以使用随机方法。假设您有一个数据集data,它是大量元组(X, Y),其中Y 是病眼信息(0 或1)。您可以为您的数据集准备一个包装器,它通过所有未患病的眼睛并以 0.3 / 0.7 的概率通过患病的眼睛(您只需要数据集中 30% 的患病眼睛)。

      from random import random
      
      
      def wrapper(data):
          prob = 0.3 / 0.7
      
          for X, Y in data:
              if Y == 0:
                  yield X, Y
              else:
                  if random() < prob:
                      yield X, Y
      
      
      # now you can use the wrapper to extract needed information
      for X, Y in wrapper(your_dataset):
          print X, Y
      

      请注意,如果您需要多次将此包装器用作生成器并希望获得相同的结果,则必须在使用函数random() 之前设置固定随机种子。更多信息:https://docs.python.org/2/library/random.html

      【讨论】:

        猜你喜欢
        • 2016-04-22
        • 2014-01-09
        • 2016-05-08
        • 2014-06-20
        • 2020-06-04
        • 2018-01-24
        • 2015-07-04
        • 2020-04-28
        • 2017-06-08
        相关资源
        最近更新 更多