web-dev-qa-db-ja.com

マルチラベル分類子でStratified-k倍を使用できない

次のコードはKFold検証を行うために使用されますが、それがエラーを投げているようにモデルを訓練する予定です。

ValueError: Error when checking target: expected dense_14 to have shape (7,) but got array with shape (1,)
 _

私のターゲット変数には7つのクラスがあります。 LabelEncoderを使用してクラスを数値にエンコードしています。

このエラーを見ることで、クラスをエンコードするためにINTOMultiLabelBinarizerを変更している場合。私は次の誤りを得ています

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

以下は、Kfold検証のコードです

skf = StratifiedKFold(n_splits=10, shuffle=True)
scores = np.zeros(10)
idx = 0
for index, (train_indices, val_indices) in enumerate(skf.split(X, y)):
    print("Training on fold " + str(index+1) + "/10...")
    # Generate batches from indices
    xtrain, xval = X[train_indices], X[val_indices]
    ytrain, yval = y[train_indices], y[val_indices]
    model = None
    model = load_model() //defined above

    scores[idx] = train_model(model, xtrain, ytrain, xval, yval)
    idx+=1
print(scores)
print(scores.mean())
 _

私は何をすべきかわからない。私のモデルに成層k倍を使いたいです。私を助けてください。

6
Sai Pavan

MultiLabelBinarizerクラス数の長さのベクトルを返します。

StratifiedKFold _ - 分割 あなたのデータセットを見ると、それが一次元ターゲット変数を受け入れるだけであるが、ターゲット変数をディメンションで渡しようとしているのは[n_samples, n_classes]

StrateFied Splitは基本的にあなたのクラスの配布を保存します。そして、あなたがそれについて考えるならば、あなたがマルチラベルの分類問題があるならば、それは多くの意味を持ちません。

ターゲット変数のクラスのさまざまな組み合わせの観点から分布を保存したい場合は、回答が ここで 独自のストレート分割関数を定義できる2つの方法を説明しています。

アップデート:

ロジックは次のようなものです。

nクラスとターゲット変数があると仮定すると、これらのnクラスの組み合わせです。あなたは(2^n) - 1の組み合わせ(すべての0sを含めていない)を持つでしょう。各組み合わせを考慮して新しいターゲット変数を新しいラベルとして作成できるようになりました。

たとえば、n=3の場合、7の一意の組み合わせがあります。

 1. [1, 0, 0]
 2. [0, 1, 0]
 3. [0, 0, 1]
 4. [1, 1, 0]
 5. [1, 0, 1]
 6. [0, 1, 1]
 7. [1, 1, 1]

この新しいターゲット変数にすべてのラベルをマッピングします。これで、あなたの問題を簡単に見ることができますマルチラベル分類の代わりにマルチクラス分類。

これで、ターゲットとしてy_newを使用してStartefiedKFoldを直接使用できます。分割が完了したら、ラベルを背面にマッピングできます。

コードサンプル:

import numpy as np

np.random.seed(1)
y = np.random.randint(0, 2, (10, 7))
y = y[np.where(y.sum(axis=1) != 0)[0]]

出力:

array([[1, 1, 0, 0, 1, 1, 1],
       [1, 1, 0, 0, 1, 0, 1],
       [1, 0, 0, 1, 0, 0, 0],
       [1, 0, 0, 1, 0, 0, 0],
       [1, 0, 0, 0, 1, 1, 1],
       [1, 1, 0, 0, 0, 1, 1],
       [1, 1, 1, 1, 0, 1, 1],
       [0, 0, 1, 0, 0, 1, 1],
       [1, 0, 1, 0, 0, 1, 1],
       [0, 1, 1, 1, 1, 0, 0]])

ラベルはクラスベクトルをエンコードします。

from sklearn.preprocessing import LabelEncoder

def get_new_labels(y):
    y_new = LabelEncoder().fit_transform([''.join(str(l)) for l in y])
    return y_new

y_new = get_new_labels(y)

出力:

array([7, 6, 3, 3, 2, 5, 8, 0, 4, 1])
4
panktijk