如何在 scikit learn 中进行欠采样?
Posted
技术标签:
【中文标题】如何在 scikit learn 中进行欠采样?【英文标题】:How to perform under sampling in scikit learn? 【发布时间】:2015-05-26 01:47:13 【问题描述】:我们有一个视网膜数据集,其中患病的眼睛信息占信息的 70%,而未患病的眼睛占剩余的 30%。我们想要一个数据集,其中患病和未患病的样本在数量上应该相等。是否有任何可用的功能可以帮助我们做同样的事情?
【问题讨论】:
【参考方案1】:您可以使用np.random.choice
进行如前所述的简单欠采样,但问题可能是您的某些随机样本非常相似,因此会歪曲数据集。
更好的选择是使用imbalanced-learn 包,它有多个用于平衡数据集的选项。可以在here 找到一个很好的教程和描述。
该软件包列出了一些很好的欠采样选项(来自他们的 github):
带放回的随机多数欠采样 提取多数-少数 Tomek 链接 使用聚类质心进行欠采样 NearMiss-(1 & 2 & 3) 压缩最近邻 单面选择 小区清洁规定 编辑最近的邻居 实例硬度阈值 重复编辑的最近邻居 AllKNN
【讨论】:
【参考方案2】:我会选择使用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)
【讨论】:
如果我错了请纠正我,但是在选择健康组之后再选择与非健康组相同大小的子样本,不会是:` 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
【讨论】:
以上是关于如何在 scikit learn 中进行欠采样?的主要内容,如果未能解决你的问题,请参考以下文章