Sklearn StratifiedKFold:ValueError:支持的目标类型是:('binary','multiclass')。得到'多标签指标'

时间:2018-01-29 18:48:42

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

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

<div class="container-fluid">
    <div class="card-deck mb-3 text-center">

        <div class="card box-shadow text-center">
            <div class="card-header">
                <h4 class="my-0 mb-3">Card A</h4>       
                <ul class="nav nav-tabs card-header-tabs justify-content-center" role="tablist">
                  <li class="nav-item">
                    <a class="nav-link active" id="optionA-tab" data-toggle="tab" href="#optionA" role="tab" aria-controls="optionA" aria-selected="true">Option A</a>
                  </li>
                  <li class="nav-item">
                    <a class="nav-link" id="optionB-tab" data-toggle="tab" href="#optionB" role="tab" aria-controls="optionB" aria-selected="false">Option B</a>
                  </li>
                  <li class="nav-item">
                    <a class="nav-link" id="optionC-tab" data-toggle="tab" href="#optionC" role="tab" aria-controls="optionC" aria-selected="false">Option C</a>
                  </li>
                </ul>
            </div>
            <div class="card-body tab-content pl-0 pr-0 pb-0 mb-0">
                <div class="tab-pane fade pl-0 pr-0 show active " id="optionA" role="tabpanel" aria-labelledby="optionA-tab">
                    <h4 class="card-title pl-3 pr-3">Some Text for Option A</h4>
                    <!--Card image at card bottom-->
                    <img class="card-img-bottom" src="img/ImageA.jpg">              
                    <!--/.Card image at card bottom-->
                </div>
                <div class="tab-pane fade pl-0 pr-0" id="optionB" role="tabpanel" aria-labelledby="optionB-tab">
                    <h4 class="card-title pl-3 pr-3">Some Text for Option B</h4>
                    <!--Card image at card bottom-->
                    <img class="card-img-bottom" src="img/ImageB.jpg">              
                    <!--/.Card image at card bottom-->
                </div>
                <div class="tab-pane fade pl-0 pr-0" id="optionC" role="tabpanel" aria-labelledby="optionC-tab">
                    <h4 class="card-title pl-3 pr-3">Some Text for Option C</h4>
                    <!--Card image at card bottom-->
                    <img class="card-img-bottom align-bottom align-img-bottom" src="img/Grey.jpg">              
                    <!--/.Card image at card bottom-->
                </div>
            </div>
        </div>

        <div class="card mb-8 box-shadow">
            <div class="card-header">
                <h4 class="my-0">Card B</h4>
            </div>
            <div class="container-fluid">
            Lorem ipsum dolor sit amet, consectetur adipisici elit, sed eiusmod tempor incidunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquid ex ea commodi consequat. Quis aute iure reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint obcaecat cupiditat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
            Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
            </div>
        </div>

    </div>
</div>

4 个答案:

答案 0 :(得分:15)

keras.utils.to_categorical生成一个热门编码的类向量,即错误消息中提到的multilabel-indicatorStratifiedKFold并非旨在使用此类输入;来自split方法docs

  

split (X,y,groups = None)

     

[...]

     

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

     

监督学习问题的目标变量。分层基于y标签完成。

即。您的y必须是班级标签的一维数组。

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

答案 1 :(得分:4)

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

from sklearn.utils.multiclass import type_of_target
type_of_target(y)

'multilabel-indicator'

通过其文档字符串:

  
      
  • 'binary':y包含<= 2个离散值,为1d或一列   向量。
  •   
  • '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)

答案 2 :(得分:1)

在我的情况下,x是2D矩阵,y也是2d矩阵,即实际上是多类多输出情况。我像往常一样为np.zeros(shape=(n,1))y传递了一个虚拟x。完整代码示例:

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]

答案 3 :(得分:0)

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

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

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