【问题标题】:How to perform MultiLabel stratified sampling?如何执行 MultiLabel 分层抽样?
【发布时间】:2019-04-22 01:39:15
【问题描述】:

我正在处理多标签数据,我想使用分层抽样。假设我有 10 个班级,我们称它们为“ABCDEFGHIJ”。我有一个包含 10 列的数据框,每个标签对应于包含有关条目的其余信息的每个标签。我可以在 n_entry*10 矩阵中提取这 10 列,我将其称为 label_values

例如,一行 label_values 看起来像 [0,0,1,1,0,0,0,0,0,0],而这一特定行表示该条目具有标签 C 和标签 D。

我想在训练和验证集中执行我的数据拆分,并且我希望在训练和验证中每个标签的比例相同。为了执行我的拆分,我使用了 Sklearn train_test_split 函数(在我需要分层之前),它恰好有一个参数分层。当前的行为是将 multi_label 行为变成多类行为(我们认为 [A,B] 是一个全新的类,与 A 类和 B 类完全不同)。因此,有些类只有 1 个元素,这会触发错误:

ValueError("The least populated class in y has only 1"
                         " member, which is too few. The minimum"
                         " number of groups for any class cannot"
                         " be less than 2.")

来自 StratifiedShuffleSplit 类的 _iter_indices 的 sklearn/model_selection/_split.py:

if np.min(class_counts) < 2:
        raise ValueError("The least populated class in y has only 1"
                         " member, which is too few. The minimum"
                         " number of groups for any class cannot"
                         " be less than 2.")

我的解决方法是重写此方法以删除此检查。这很有效,我可以在训练和验证之间更好地重新分配我的标签。但是,我的一个带有 2 个元素的标签完全在训练集中。这正常吗?

其他问题:这是解决此问题的好方法,还是您认为有更好的方法可以在 multi_label 中对 train_test_split 进行分层?

【问题讨论】:

    标签: python scikit-learn


    【解决方案1】:

    如您所知,@ 987654321的分层不会单独考虑标签,而是作为“标签集”。这根本不适用于多标签数据,因为唯一组合的数量以标签数量呈指数级增长。在您的示例中,有1024种不同的标签组合。您需要至少两次执行双向拆分,即便如此,您只能获得每个分裂每个组合的一个示例。

    禁用禁用的拆分可能有点有效,因为重复标签集可以分层,但对于唯一标签集,您只需允许Scikit-reansure将它们随机分割,这无用或有效。

    Sechidis、Tsoumakas 和 Vlahavas 于 2011 年提出了一种名为 Iterative Stratification 的算法,该算法通过分别考虑每个标签来拆分多标签数据集,从具有最少正例的标签开始,一直到具有最佳代表性的标签。

    目前可以使用的两种实现:

    1. iterative-stratification
    2. Scikit-Multilearn's iterative_train_test_split()

    假设您希望双向拆分为这3标签(L1,L2,L3)样本:

    L1 L2 L3
    --------
    0  0  0
    0  0  1
    0  1  0
    0  1  1
    1  0  0 
    1  0  1
    1  1  0
    1  1  1
    

    有8个唯一标签集,但每个标签有4个正例。而不是随机分割,迭代分层将尝试为您提供两个包含来自每个标签的平衡数量的分割。示例拆分可能如下所示:

    Split 1
    -------
    L1 L2 L3
    0  0  1
    0  1  0
    1  0  1
    1  1  0
    
    Split 2
    -------
    L1 L2 L3
    0  0  0
    0  1  1
    1  0  0
    1  1  1
    

    请注意,即使每个标签集都保持唯一,每个标签现在都有一个很好的差距,甚至平衡。

    【讨论】:

      【解决方案2】:

      对您来说最简单的解决方案是使用带有skmultilearn 的多标签分层。快速示例:

      from skmultilearn.model_selection import iterative_train_test_split
      t_train, y_train, t_test, y_test = iterative_train_test_split(X, y, test_size = 0.2)
      

      请考虑到迭代分层很慢,并且对于大型数据集可能非常耗时。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-01-24
        • 1970-01-01
        • 2022-10-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-25
        相关资源
        最近更新 更多