如何在scikit中进行抽样学习?

时间:2015-03-23 05:53:08

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

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

3 个答案:

答案 0 :(得分:14)

我会选择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)

答案 1 :(得分:2)

作为变体,您可以使用随机方法。假设您有一个数据集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

答案 2 :(得分:1)

您可以按照前面的建议将COUNT()用于天真下的采样,但是问题可能是您的某些随机采样非常相似,因而曲解了数据集。

一个更好的选择是使用imbalanced-learn程序包,该程序包具有多个用于平衡数据集的选项。 here可以找到很好的教程和说明。

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

  
      
  • 随机多数采样不足并替换
  •   
  • 提取少数族裔Tomek链接
  •   
  • 使用聚类质心进行欠采样
  •   
  • NearMiss-(1&2&3)
  •   
  • 最近的邻居
  •   
  • 单面选择
  •   
  • 邻居清洁规则
  •   
  • 最近的邻居
  •   
  • 实例硬度阈值
  •   
  • 重复编辑过的最近邻居
  •   
  • AllKNN
  •