MENU

python 手書き数字の判定

個人的なおさらい

plt.imshowのオプションのcmapは色を指定できる。

モジュールとはpyhtonで関数やクラスなどをまとめて書いたファイルをモジュールという。

import , from~import の違い。

import モジュール名で指定したモジュールを読み込める。

モジュール.関数名、モジュール.変数名、のようにモジュール内で定義された関数やグローバル変数などを使用できる。

 

特定のオブジェクト(関数や変数、クラスなど)を読み込みたい場合。

from モジュール名 import オブジェクト名で読み込める。

 

 

本編

前提知識ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

scikit-learnで標準で用意されている手書き数字データセットの利用方法。

読み込み

from sklearn import datasets

digits = datasets.load_digits()

 

digitsの中身、つまり読み込んだデータは辞書型になっており次のような仕組みになっている。

digits.images: 画像データの配列。

digits.target: データがどの数字を表すのかのラベルデータ。

 

 

読み込んだ画像データの一つを見てみると

f:id:hanamichi_sukusuku:20201223192641p:plain

上が画像、下の数字が各ピクセルの値。

このデータは8✖️8ピクセルであり、各ピクセルは0から16までの値で表されている。

0が透明(背景が黒なのでここでは黒い部分)、16が線のある部分(白色)を表している。

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

ここからが本題

f:id:hanamichi_sukusuku:20201223194125p:plain


これはscikit-learnで用意されている手書き数字のデータを機械学習に与えて判定するとどのくらいの精度なのか確認している。

from sklearn.model_selection import train_test_split
from sklearn import datasets, svm, metrics
from sklearn.metrics import accuracy_score

必要なモジュールをインポート

from sklearn.model_selection import train_test_split

この記述はscikit-learnのtrain_test_split()関数を使うと、NumPy配列ndarraやリストなどを二分割にでき、今回は機械学習を用いるのでデータを学習用、テスト用に分割して検証するためにインポートしている。

 

from sklearn import datasets, svm, metrics

この記述はscikit-learnから使用するオブジェクトを複数指定している。

 

datasetsは手書き数字データなどのデータセットが格納されている。

 

svm機械学習のモデルの一つで分類または回帰分析を行うモデル。アルゴリズムの一種。

 

meticsは作成したモデルを評価を行うオブジェクト。

from sklearn.metrics import accuracy_score

この部分でsklearn.metricsモジュールからaccuracy_screメソッドをそのまま使えるようにしている。accuracy_scoreメソッドは正解率を出力するメソッドで

accuracy_score(正しい結果,予測結果) このように指定することで正解率を出力できる。

 

データ読み込み


digits = datasets.load_digits()  ここで手書き数字データ読み込み
x = digits.images        画像データの配列をxに代入
y = digits.target        データがどの数字を表すかのラベルデータを代入
x = x.reshape*1      二次元配列から一次元配列に変換している

reshape( )を使うと配列の次元を変換することができる。

二次元配列として表現されている画像データを一次元配列にする理由は一つ一つの画像データをまとめるためだと思う。(列数が64の配列を作っていることから推察した個人的な考え)

  p =numpy.array( [[0,1],[2,3],[4,5]]) こんな配列があったとする。

 p.reshape(-1)の場合

  [0 1 2 3 4 5 ]

一次元の配列になる。-1を指定した場合は行数は一行になり、列数は元の配列の要素数になる。  

 p.reshape(-1, 2)の場合

     [[0 1]

      [2 3]

      [4 5]]

-1で上記のような配列になり、第二引数に2を指定しているので要素数が2個ずつの二次元配列が出来上がる。

 

  p.reshape(2, 3)の場合

 [[0 1 2]

     [3 4 5]]

 2行3列の配列が出来上がる。

 

つまり、第一引数に正の整数を指定した時はそれが行数、-1を指定した時は一次元の1行の配列になり、第二引数に指定した値が列数になる。

 

ここでのx.reshape(-1, 64)は列数を64にした一次元の配列を複数作成している。

列数が64なのは上記の一つの画像に関して説明している通り、ここで読み込んだ画像の一つ一つは64個の要素で一つの画像データであるため列数が64の配列にまとめていくことで一つ一つの画像データをまとめていることになる。

 

データを学習用とテスト用に分割する 


x_train, x_test, y_train, y_test = \
 train_test_split(x, y, test_size=0.2)

 

train_test_split()で画像データとラベルデータをtest_size=0.2を指定することで学習用8割、テスト用2割に分割している。

書籍に=\と書いてあったが

x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2)このように記述しても変化はなかったのでどちらでもいいと思う。調べたけど違いがわからなかった。違ってたらごめんなさい。

 

データを学習 


clf = svm.SVC()          学習用モデルの作成
clf.fit(x_train, y_train)        fit()メソッドでモデルに学習させる

 

予測して精度を確認する 


y_pred = clf.predict(x_test)     predict()メソッドで結果を予測
print(accuracy_score(y_test, y_pred)) accuracy_score()で正解率を出力

 

 

以上

*1:-1, 64