如何进行分层下采样?

问题描述 投票:0回答:1

我需要使用机器学习技术建立蛋白质序列的分类模型。每个观察值都可以分类为 0 或 1。但是,我注意到我的训练集总共包含 170 000 个观察值,其中只有 5000 个被标记为 1。因此,我希望对观察值数量进行下采样标记为 0 到 5000。

我当前在模型中使用的特征之一是序列的长度。如何对 0 类的数据进行下采样,同时确保 length_sequence 的分布与 1 类中的分布相似?

这是第 1 类的 length_sequence 的直方图: enter image description here

这是 0 类的 length_sequence 的直方图: enter image description here

您可以看到,在这两种情况下,长度都在 2 到 255 个字符之间。然而,0 类有更多的观察结果,而且它们也往往比 0 类中看到的观察结果要长得多。

如何对 0 类进行下采样并使新的直方图看起来与 1 类中的直方图相似?

我正在尝试使用 scikit-learn 进行分层下采样,但我陷入困境。

machine-learning scikit-learn downsampling
1个回答
0
投票

如果您希望两个类别具有相似的

length_sequence
直方图,那么您可以尝试使用 倾向得分匹配。这个想法是使用要分层的变量(在本例中为
length_sequence
)来预测类别
y
,然后在逻辑上进行匹配。

您可以在 Python 中执行此操作,例如使用 statkit

 中的 
balanced_downsample 函数:

from statkit.dataset import balanced_downsample

X = pd.DataFrame({
  'length_sequence': [150, 200, 170,...],
  'hydrophobicity': [0.2, 0.3, 0.3, ...],
}) 
y = pd.Series([0, 1, 0,...])

# Subselect indices labelled y=0, stratified on `length_sequence`.
idx_zero = balanced_downsample(X[['length_sequence']], y, ratio=1)

# Take all y=1 labelled examples and combine with y=0 subselection.
idx_one = y.index[y.astype(bool)]
selection = np.concatenate([idx_zero, idx_one])
X_downsampled, y_downsampled = X.loc[selection], y.loc[selection]

(披露:我是 statkit 的作者。)

注意对

length_sequence
进行下采样后,您不能再将其用作分类器的输入,因为该变量不再提供信息。

有关更多详细信息,我将参考本文的第 3 节: Rosenbaum-Ruben,“倾向评分在因果效应观察研究中的核心作用”,Biometrika 70, 1,第 41-55 页 (1983)。

© www.soinside.com 2019 - 2024. All rights reserved.