如何在 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 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

【讨论】:

以上是关于如何在 scikit learn 中进行欠采样?的主要内容,如果未能解决你的问题,请参考以下文章

scikit-learn 中的不平衡

如何对不平衡的多类数据集进行欠采样? (Python)

Python 中用 XGBoost 和 scikit-learn 进行随机梯度增强

使用不平衡学习库的特征重要性

使用 scikit-learn 并行生成随机森林

如 scikit-learn 的文档中所述,如何在 cv 中使用 TimeSeriesSplit