Python Sklearn StratifiedKFold: ValueError: 支持的目标类型是: ('binary', 'multiclass')。得到了“多标签指标”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/48508036/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Sklearn StratifiedKFold: ValueError: Supported target types are: ('binary', 'multiclass'). Got 'multilabel-indicator' instead
提问by jKraut
Working with Sklearn stratified kfold split, and when I attempt to split using multi-class, I received on error (see below). When I tried and split using binary, it works no problem.
使用 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.
采纳答案by desertnaut
keras.utils.to_categorical
produces a one-hot encoded class vector, i.e. the multilabel-indicator
mentioned in the error message. StratifiedKFold
is not designed to work with such input; from the split
method docs:
keras.utils.to_categorical
产生一个单热编码的类向量,即multilabel-indicator
错误消息中提到的。StratifiedKFold
并非设计用于处理此类输入;从split
方法文档:
split
(X, y, groups=None)[...]
y: array-like, shape (n_samples,)
The target variable for supervised learning problems. Stratification is done based on the y labels.
split
(X, y, 组=无)[...]
y: 类似数组,形状 (n_samples,)
监督学习问题的目标变量。分层是基于 y 标签完成的。
i.e. your y
must be a 1-D array of your class labels.
即你y
必须是你的类标签的一维数组。
Essentially, what you have to do is simply to invert the order of the operations: split first (using your intial y_train
), and convert to_categorical
afterwards.
本质上,您要做的只是反转操作的顺序:首先拆分(使用您的 intial y_train
),然后转换to_categorical
。
回答by wilmeragsgh
Call to split()
like this:
打电话给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]
回答by nocibambi
I bumped into the same problem and found out that you can check the type of the target with this util
function:
我遇到了同样的问题,发现你可以用这个util
函数检查目标的类型:
from sklearn.utils.multiclass import type_of_target
type_of_target(y)
'multilabel-indicator'
From its docstring:
从它的文档字符串:
- 'binary':
y
contains <= 2 discrete values and is 1d or a column vector.- 'multiclass':
y
contains more than two discrete values, is not a sequence of sequences, and is 1d or a column vector.- 'multiclass-multioutput':
y
is a 2d array that contains more than two discrete values, is not a sequence of sequences, and both dimensions are of size > 1.- 'multilabel-indicator':
y
is a label indicator matrix, an array of two dimensions with at least two columns, and at most 2 unique values.
- 'binary':
y
包含 <= 2 个离散值并且是 1d 或列向量。- 'multiclass':
y
包含两个以上的离散值,不是序列序列,是1d或列向量。- 'multiclass-multioutput':
y
是一个包含两个以上离散值的二维数组,不是序列序列,并且两个维度的大小都大于 1。- 'multilabel-indicator':
y
是一个标签指示矩阵,一个二维数组,至少有两列,最多有 2 个唯一值。
With LabelEncoder
you can transform your classes into an 1d array of numbers (given your target labels are in an 1d array of categoricals/object):
随着LabelEncoder
您可以将您的类成数字的一维数组(给你的目标标签是在categoricals的一维数组/对象):
from sklearn.preprocessing import LabelEncoder
label_encoder = LabelEncoder()
y = label_encoder.fit_transform(target_labels)
回答by shadi
In my case, x
was a 2D matrix, and y
was also a 2d matrix, i.e. indeed a multi-class multi-output case. I just passed a dummy np.zeros(shape=(n,1))
for the y
and the x
as usual. Full code example:
在我的例子中,x
是一个二维矩阵,y
也是一个二维矩阵,即确实是一个多类多输出案例。我只是通过一个虚拟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]