Python 如何进行多标签分层抽样?

Python 如何进行多标签分层抽样?,python,scikit-learn,Python,Scikit Learn,我处理的是多标签数据,我想使用分层采样。假设我有10个类,我们称它们为“ABCDEFGHIJ”。我有一个dataframe,其中10列对应于每个标签,其中包含关于条目的其余信息。我可以提取n_entry*10矩阵中的10列,我将其称为label_值 例如,标签_值的一行看起来像[0,0,1,1,0,0,0,0],此特定行表示条目具有标签C和标签D 我希望在培训和验证集中对我的数据进行拆分,并且我希望在培训和验证中每个标签的比例相同。为了执行拆分,我使用了Sklearn train_test_sp

我处理的是多标签数据,我想使用分层采样。假设我有10个类,我们称它们为“ABCDEFGHIJ”。我有一个dataframe,其中10列对应于每个标签,其中包含关于条目的其余信息。我可以提取n_entry*10矩阵中的10列,我将其称为label_值

例如,标签_值的一行看起来像[0,0,1,1,0,0,0,0],此特定行表示条目具有标签C和标签D

我希望在培训和验证集中对我的数据进行拆分,并且我希望在培训和验证中每个标签的比例相同。为了执行拆分,我使用了Sklearn train_test_split函数(在我需要分层之前),它恰好有一个参数分层。当前的行为是使多标签行为变成多类行为(我们认为[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.")
来自分层shufflesplit类的_iter_索引中的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.")
如果np.min(类_计数)<2:
raise VALUERROR(“y中填充最少的类只有1”
成员,太少。最小值
“任何类的组数都不能”
“小于2。”)
我的修复方法是重写此方法以删除此支票。这是可行的,我可以在训练和验证之间更好地重新划分标签。但是,我的其中一个带有2个元素的标签完全在列车集中。这正常吗


另一个问题:这是处理这个问题的好方法,还是你认为在多标签中有一个更好的方法来获得分层的TraceTestTraceS分裂?正如你注意到的,分层不单独考虑标签,而是作为一个“标签集”。这对于多标签数据根本不起作用,因为唯一组合的数量随标签数量呈指数增长。在您的示例中,有1024种不同的标签组合。要执行双向拆分,您至少需要两倍于此,即使这样,每次拆分也只能得到一个组合示例

禁用检查的拆分可能有一定的效果,因为重复的标签集可以分层,但对于唯一的标签集,您只是允许scikit learn随机拆分它们,这既没有用处也没有效果

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

目前,您可以使用以下两种实现:

  • scikit多重学习
  • 假设您希望对这些三标签(L1、L2、L3)样本进行双向拆分:

    有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
    

    请注意,尽管每个标签集都是唯一的,但现在每个标签在分割之间都有一个很好的、均匀的平衡。

    最简单的解决方案是使用多标签分层。快速示例:

    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)
    
    请考虑到迭代分层是缓慢的,对于大型数据集可能相当耗时

    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)