質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.06%

keras:MNISTの畳み込みニューラルネットワークで混同行列は使えない?

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 692

python_2019

score 66

mnistのモデル評価を行うために、混同行列を取得しようとすると、エラーが発生します。
通常のディープラーニングの2分類では、ちゃんと混同行列を得ることができていたのですが、何故でしょうか?
mnistは10分類なので、混同行列はできないのでしょうか?

お詳しい方、ご指導をお願いいたします。

(以下、全てのコードとエラーメッセージです。)

import keras
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPooling2D
#from keras.optimizers import RMSprop
#from keras.utils import np_utils
#from sklearn.datasets import fetch_mldata

# データを高速かつ効率的に使えるPandasをインポート
import pandas as pd

# 数値計算を効率的に行うNumpyをインポート
import numpy as np

# グラフが簡単に描写できるMatplotlibをインポート
import matplotlib
import matplotlib.pyplot as plt

# MNISTデータを読込む
(x_train, y_train), (x_test, y_test) = mnist.load_data()

# MNISTデータを加工する

# 1次元に加工する場合(畳み込みは2次元)(デフォルトは2次元)
#x_train  = x_train.reshape(60000, 784)
#x_test   = x_test.reshape(10000, 784)

# データを float 型に変換
x_train  = x_train.astype('float32')
x_test   = x_test.astype('float32')

# 0〜255 までの範囲のデータを 0〜1 までの範囲に変更(正規化)
x_train /= 255
x_test  /= 255

# 分類するクラス数
y_train  = keras.utils.to_categorical(y_train, 10)
y_test   = keras.utils.to_categorical(y_test, 10)

# 後の評価で使用?
y_test_backup = y_test


# 両方のサイズを確認

print("x_train.shape(学習用の画像データ) : ", x_train.shape)
print("y_train_shape(学習用の正解データ) : ", y_train.shape)
print("x_test.shape(テスト用の画像データ) : ", x_test.shape)
print("y_test.shape(テスト用の正解データ) : ", y_test.shape)

x_train.shape(学習用の画像データ) :  (60000, 28, 28)
y_train_shape(学習用の正解データ) :  (60000, 10)
x_test.shape(テスト用の画像データ) :  (10000, 28, 28)
y_test.shape(テスト用の正解データ) :  (10000, 10)

# 28x28x1のサイズへ変換
x_train = x_train.reshape(x_train.shape[0], 28, 28,1)
x_test = x_test.reshape(x_test.shape[0], 28, 28,1)

# モデルの宣言
model = Sequential()

# 先に作成したmodelへレイヤーを追加
model.add(Conv2D(32, kernel_size=(3, 3),
                 activation='relu',
                 input_shape=(28,28,1)))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dense(10, activation='softmax'))

# Learnig Processの設定
model.compile(loss='categorical_crossentropy',
              optimizer='sgd',
              metrics=['accuracy'])

# 注意 - 数分程度かかる
# モデルの訓練(エポック数)
model.fit(x_train, y_train, epochs=1)


Epoch 1/1
60000/60000 [==============================] - 19s 318us/step - loss: 0.4984 - acc: 0.8590
<keras.callbacks.History at 0x1fa3aaad5c0>

# テストデータを使ってモデルの評価
loss_and_metrics = model.evaluate(x_test, y_test, batch_size=128)
print(loss_and_metrics)

10000/10000 [==============================] - 1s 54us/step
[0.2483551863193512, 0.9253]

# 評価の実行

from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
predict_classes = model.predict_classes(x_test)

score = model.evaluate(x_test,y_test)
print('正確度(accuracy):', score[1])
print(' ')
#print('精度(正確度):{:.3f}'.format(accuracy_score(y_test, predict_classes)))
#print('適合率:{:.3f}'.format(precision_score(y_test, predict_classes)))
#print('再現率:{:.3f}'.format(recall_score(y_test, predict_classes)))
#print('f-1値:{:.3f}'.format(f1_score(y_test, predict_classes)))

# 混同行列(Confusion Matrix)
print(' ')
from sklearn.metrics import confusion_matrix

print(confusion_matrix(y_test, predict_classes))

10000/10000 [==============================] - 1s 60us/step
正確度(accuracy): 0.9253
 
 
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-7-0c069648309b> in <module>
     16 from sklearn.metrics import confusion_matrix
     17 
---> 18 print(confusion_matrix(y_test, predict_classes))

C:\python\anaconda\pgm\lib\site-packages\sklearn\metrics\classification.py in confusion_matrix(y_true, y_pred, labels, sample_weight)
    251 
    252     """
--> 253     y_type, y_true, y_pred = _check_targets(y_true, y_pred)
    254     if y_type not in ("binary", "multiclass"):
    255         raise ValueError("%s is not supported" % y_type)

C:\python\anaconda\pgm\lib\site-packages\sklearn\metrics\classification.py in _check_targets(y_true, y_pred)
     79     if len(y_type) > 1:
     80         raise ValueError("Classification metrics can't handle a mix of {0} "
---> 81                          "and {1} targets".format(type_true, type_pred))
     82 
     83     # We can't have more than one value on y_type => The set is no more needed

ValueError: Classification metrics can't handle a mix of multilabel-indicator and multiclass targets

以下、printの結果です。

print(y_test)
print(predict_classes)

[[0. 0. 0. ... 1. 0. 0.]
 [0. 0. 1. ... 0. 0. 0.]
 [0. 1. 0. ... 0. 0. 0.]
 ...
 [0. 0. 0. ... 0. 0. 0.]
 [0. 0. 0. ... 0. 0. 0.]
 [0. 0. 0. ... 0. 0. 0.]]
[7 2 1 ... 4 5 6]
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • hayataka2049

    2019/11/07 19:41

    y_test, predict_classesそれぞれのオブジェクトの型、要素の型、shapeとndim、printした結果を教えて下さい。

    キャンセル

  • python_2019

    2019/11/08 10:25

    ご連絡ありがとうございます。

    全てのコードとエラーメッセージ、printした結果を追記いたしました。

    お手数お掛け致しますが、ご指導方よろしくお願いいたします。

    キャンセル

回答 2

checkベストアンサー

+1

y_testkeras.utils.to_categoricalを通す前のものにしてください。

たぶん

# 分類するクラス数
y_train  = keras.utils.to_categorical(y_train, 10)
y_test   = keras.utils.to_categorical(y_test, 10)

# 後の評価で使用?
y_test_backup = y_test

ここは上下を入れ替えておいたほうが良い。

y_test_backup = y_test

y_train  = keras.utils.to_categorical(y_train, 10)
y_test   = keras.utils.to_categorical(y_test, 10)

あとはy_test_backupの方で混同行列の作成を試してください。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/11/08 11:39

    ご指導どおり修正しましたら、エラーがなくなりました。

    とても助かりました。
    どうもありがとうございました。

    キャンセル

0

エラーメッセージによるとscikitlearnのconfusion_matrixは多クラス分類に対応していないので、pandasのcrosstabを使うといいかと思います。

import pandas as pd
print(pd.crosstab(y_test,predict_classes))

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/11/07 19:43 編集

    > confusion_matrixは多クラス分類に対応していない
    それはないです。この関数で多クラス分類の混同行列自体は出るので、与えている配列に問題がありそうです。
    >>> confusion_matrix([0,0,0,1,1,1,2,2,2], [0,0,1,0,2,1,1,2,2,])
    array([[2, 1, 0],
    [1, 1, 1],
    [0, 1, 2]])

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.06%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る