【问题标题】:Sklearn StratifiedKFold: ValueError: Supported target types are: ('binary', 'multiclass'). Got 'multilabel-indicator' insteadSklearn StratifiedKFold:ValueError:支持的目标类型是:('binary','multiclass')。改为使用“多标签指示符”
【发布时间】:2018-07-08 13:09:51
【问题描述】:

使用 Sklearn 分层 kfold 拆分,当我尝试使用多类拆分时,我收到错误消息(见下文)。当我尝试使用二进制进行拆分时,它没有问题。

num_classes = len(np.unique(y_train))
y_train_categorical = keras.utils.to_categorical(y_train, num_classes)
kf=StratifiedKFold(n_splits=5, shuffle=True, random_state=999)

# splitting data into different folds
for i, (train_index, val_index) in enumerate(kf.split(x_train, y_train_categorical)):
    x_train_kf, x_val_kf = x_train[train_index], x_train[val_index]
    y_train_kf, y_val_kf = y_train[train_index], y_train[val_index]

ValueError: Supported target types are: ('binary', 'multiclass'). Got 'multilabel-indicator' instead.

【问题讨论】:

    标签: python machine-learning keras scikit-learn cross-validation


    【解决方案1】:

    如果您的目标变量是连续的,则使用简单的 KFold 交叉验证而不是 StratifiedKFold。

    from sklearn.model_selection import KFold
    kfold = KFold(n_splits=5, shuffle=True, random_state=42)
    

    【讨论】:

      【解决方案2】:

      补充@desertnaut 所说的,为了将您的one-hot-encoding 转换回一维数组,您只需要做的是:

      class_labels = np.argmax(y_train, axis=1)
      

      这将转换回您的类的初始表示。

      【讨论】:

        【解决方案3】:

        我遇到了同样的问题,发现你可以用这个util函数检查目标的类型:

        from sklearn.utils.multiclass import type_of_target
        type_of_target(y)
        
        'multilabel-indicator'
        

        来自其文档字符串:

        • 'binary':y 包含
        • 'multiclass':y 包含两个以上的离散值,不是 序列的序列,并且是 1d 或列向量。
        • 'multiclass-multioutput':y 是一个二维数组,包含更多 不是两个离散值,不是序列序列,并且两者 尺寸的大小 > 1。
        • 'multilabel-indicator':y是一个标签指示矩阵,一个数组 具有至少两列且最多 2 个唯一的二维 价值观。

        使用LabelEncoder,您可以将您的类转换为一维数字数组(假设您的目标标签位于一维分类/对象数组中):

        from sklearn.preprocessing import LabelEncoder
        
        label_encoder = LabelEncoder()
        y = label_encoder.fit_transform(target_labels)
        

        【讨论】:

        • 不知道原因,但它实际上对我不起作用
        【解决方案4】:

        像这样打电话给split()

        for i, (train_index, val_index) in enumerate(kf.split(x_train, y_train_categorical.argmax(1))):
            x_train_kf, x_val_kf = x_train[train_index], x_train[val_index]
            y_train_kf, y_val_kf = y_train[train_index], y_train[val_index]
        

        【讨论】:

          【解决方案5】:

          在我的例子中,x 是一个二维矩阵,y 也是一个二维矩阵,即确实是一个多类多输出的情况。我像往常一样为yx 传递了一个虚拟np.zeros(shape=(n,1))。完整代码示例:

          import numpy as np
          from sklearn.model_selection import RepeatedStratifiedKFold
          X = np.array([[1, 2], [3, 4], [1, 2], [3, 4], [3, 7], [9, 4]])
          # y = np.array([0, 0, 1, 1, 0, 1]) # <<< works
          y = X # does not work if passed into `.split`
          rskf = RepeatedStratifiedKFold(n_splits=3, n_repeats=3, random_state=36851234)
          for train_index, test_index in rskf.split(X, np.zeros(shape=(X.shape[0], 1))):
              print("TRAIN:", train_index, "TEST:", test_index)
              X_train, X_test = X[train_index], X[test_index]
              y_train, y_test = y[train_index], y[test_index]
          

          【讨论】:

          • 如果您不将标签传递给StratifiedKFold,那么它的意义何在?只需改用KFold
          • StratifiedKFold 通常会使用目标,但在我的特定快捷方式中,我为目标传递了 0,所以你是对的
          【解决方案6】:

          keras.utils.to_categorical 产生一个单热编码的类向量,即错误消息中提到的multilabel-indicatorStratifiedKFold 不适用于此类输入;来自split 方法docs

          split(X, y, groups=None)

          [...]

          y : 类数组,形状 (n_samples,)

          监督学习问题的目标变量。分层是根据 y 标签完成的。

          即你的y 必须是你的类标签的一维数组。

          基本上,您要做的只是颠倒操作的顺序:首先拆分(使用您的初始y_train),然后转换to_categorical

          【讨论】:

          • 我不认为这是一个好主意,因为在具有多类分类问题的不平衡数据集中,您想要转换它的标签的验证部分可能不包含所有类.因此,当您调用 to_categorical(val, n_class) 时,它会引发错误..
          • @Minion 这是不正确的; StratifiedKFold 负责“通过保留每个类的样本百分比来进行折叠”(docs)。在某些类的代表性非常低的非常特殊的情况下,显然建议您格外小心(和手动检查),但这里的答案仅针对一般情况,而不是针对其他假设的情况......
          • 好,感谢您的澄清……只是为了确保
          猜你喜欢
          • 2020-11-08
          • 2021-12-18
          • 2021-05-03
          • 2020-02-23
          • 2021-05-10
          • 2021-03-22
          • 2021-10-02
          • 2018-04-07
          • 2021-12-06
          相关资源
          最近更新 更多