我们有一个视网膜数据集,其中患病的眼睛信息占信息的70%,而非患病的眼睛构成剩余的30%。我们想要一个数据集,其中患病的和非患病的样本应该在数量上相等。是否有任何功能可以帮助我们做同样的事情?
我会选择与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
如前所述,您可以使用np.random.choice
进行天真的欠采样,但问题可能是您的一些随机样本非常相似,从而误报了数据集。
更好的选择是使用imbalanced-learn包,它有多个选项来平衡数据集。一个很好的教程和描述可以找到here。
该软件包列出了一些不良抽样的好选项(来自他们的github):
- 随机多数欠采样与替换
- 提取多数少数Tomek链接
- 使用Cluster Centroids进行欠采样
- NearMiss-(1&2&3)
- 凝聚的最近邻
- 单面选择
- 邻里清洁规则
- 编辑最近的邻居
- 实例硬度阈值
- 重复编辑的最近邻居
- AllKNN