【发布时间】:2015-05-26 01:47:13
【问题描述】:
我们有一个视网膜数据集,其中患病的眼睛信息占信息的 70%,而未患病的眼睛占剩余的 30%。我们想要一个数据集,其中患病和未患病的样本在数量上应该相等。是否有任何可用的功能可以帮助我们做同样的事情?
【问题讨论】:
标签: python python-2.7 dataset scikit-learn sampling
我们有一个视网膜数据集,其中患病的眼睛信息占信息的 70%,而未患病的眼睛占剩余的 30%。我们想要一个数据集,其中患病和未患病的样本在数量上应该相等。是否有任何可用的功能可以帮助我们做同样的事情?
【问题讨论】:
标签: python python-2.7 dataset scikit-learn sampling
您可以使用np.random.choice 进行如前所述的简单欠采样,但问题可能是您的某些随机样本非常相似,因此会歪曲数据集。
更好的选择是使用imbalanced-learn 包,它有多个用于平衡数据集的选项。可以在here 找到一个很好的教程和描述。
该软件包列出了一些很好的欠采样选项(来自他们的 github):
- 带放回的随机多数欠采样
- 提取多数-少数 Tomek 链接
- 使用聚类质心进行欠采样
- NearMiss-(1 & 2 & 3)
- 压缩最近邻
- 单面选择
- 小区清洁规定
- 编辑最近的邻居
- 实例硬度阈值
- 重复编辑的最近邻居
- AllKNN
【讨论】:
我会选择使用Pandas DataFrame 和numpy.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)
【讨论】:
作为一种变体,您可以使用随机方法。假设您有一个数据集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
【讨论】: