機械学習-文字認識 (プログラム)
sklearnで機械学習の文字認識をおこなってみます。sklearnでは練習用として予め1797個の画像データがあり、その画像データが0~9のどの数値に合致するかの正解データを持っています。この練習用のデータを機械学習用898個分、残りの899個分を評価用として分割し推定を行います。その後、推定した結果と予め用意していた正解データを突き合わせて正答率を表示するプログラムを作成します。
教師あり学習のサンプルとしてサポートベクターマシーンを試してみます。
使用するデータ
全データ :1797件 (学習用:898件、評価用:899件)
属性データ:0~9の画像データ
正解ラベル:数値データ(0~9)
ソースコードの流れ
1、準備作業
2、各種データの確認
3、サポートベクターマシーンの準備
4、データを学習用/評価用に分割するための準備作業
5、データを学習用/評価用に分割
6、機械学習
7、評価
8、評価の分析
ソースコード
ソースコードです。ソースコードの詳細は後で説明します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# 準備作業 from sklearn import datasets data = datasets.load_digits() #各種データの確認 print(data.DESCR) print(data.data) print(data.target_names) print(data.target) # サポートベクターマシーンの準備 from sklearn import svm clf = svm.SVC(gamma=0.001, C=100.0) #データを学習用/評価用に分割するための準備作業 #学習用:898件、評価用:899件となるようにINDEXを分割する att = data.data #attに属性データを格納 lab = data.target #labに正解ラベルを格納 n_samples = att.shape[0] #データの個数(1797件) n_train = n_samples // 2 #半分のデータを学習(898件) n_test = n_samples - n_train #評価データ数(899件) train_index = range(0,n_train) #最初の半分(range(0, 898)) test_index = range(n_train,n_samples) #残りの半分range(898, 1797) # データを学習用/評価用に分割 att_train = att[train_index] #学習用属性データ lab_train = lab[train_index] #学習用正解ラベル att_test = att[test_index] #評価用属性データ lab_test = lab[test_index] #評価用正解ラベル #機械学習 clf.fit(att_train,lab_train); #評価 print(clf.score(att_test,lab_test)) #評価の分析 ng = 0 for i,j in zip(clf.predict(att_test),lab_test): if i == j: print(i,j,"OK") else: print(i,j,"NG") ng += 1 print("{0} / {1} = {2}".format(ng,n_test,1-ng / n_test)) |
ソースコードの詳細
準備作業
1 2 |
from sklearn import datasets data = datasets.load_digits() |
各種データの確認
1 |
print(data.DESCR) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
Optical Recognition of Handwritten Digits Data Set =================================================== Notes ----- Data Set Characteristics: :Number of Instances: 5620 :Number of Attributes: 64 :Attribute Information: 8x8 image of integer pixels in the range 0..16. :Missing Attribute Values: None :Creator: E. Alpaydin (alpaydin '@' boun.edu.tr) :Date: July; 1998 This is a copy of the test set of the UCI ML hand-written digits datasets <a href="http://archive.ics.uci.edu/ml/datasets/Optical+Recognition+of+Handwritten+Digits" target="_blank" rel="noopener" data-mce-href="http://archive.ics.uci.edu/ml/datasets/Optical+Recognition+of+Handwritten+Digits">http://archive.ics.uci.edu/ml/datasets/Optical+Recognition+of+Handwritten+Digits</a> |
1 |
print(data.data) |
1 2 3 4 5 6 7 |
[[ 0. 0. 5. ..., 0. 0. 0.] [ 0. 0. 0. ..., 10. 0. 0.] [ 0. 0. 0. ..., 16. 9. 0.] ..., [ 0. 0. 1. ..., 6. 0. 0.] [ 0. 0. 2. ..., 12. 0. 0.] [ 0. 0. 10. ..., 12. 1. 0.]] |
1 |
print(data.target_names) |
1 |
[0 1 2 3 4 5 6 7 8 9] |
1 |
print(data.target) |
1 |
[0 1 2 ..., 8 9 8] |
サポートベクターマシーンの準備
1 2 |
from sklearn import svm clf = svm.SVC(gamma=0.001, C=100.0) |
データを学習用/評価用に分割するための準備作業
1 2 3 4 5 6 7 8 9 10 11 |
#データを学習用/評価用に分割するための準備作業 #学習用:898件、評価用:899件となるようにINDEXを分割する att = data.data #attに属性データを格納 lab = data.target #labに正解ラベルを格納 n_samples = att.shape[0] #データの個数(1797件) n_train = n_samples // 2 #半分のデータを学習(898件) n_test = n_samples - n_train #評価データ数(899件) train_index = range(0,n_train) #最初の半分(range(0, 898)) test_index = range(n_train,n_samples) #残りの半分range(898, 1797) |
データを学習用/評価用に分割
1 2 3 4 5 |
att_train = att[train_index] #学習用属性データ lab_train = lab[train_index] #学習用正解ラベル att_test = att[test_index] #評価用属性データ lab_test = lab[test_index] #評価用正解ラベル |
機械学習
1 |
clf.fit(att_train,lab_train); |
評価
1 |
print(clf.score(att_test,lab_test)) |
1 |
0.969966629588 |
評価の分析
1 2 3 4 5 6 7 |
ng = 0 for i,j in zip(clf.predict(att_test),lab_test): if i == j: print(i,j,"OK") else: print(i,j,"NG") ng += 1 |
1 2 3 4 5 6 7 8 |
8 8 OK 8 8 OK 4 4 OK 9 9 OK 0 0 OK 8 8 OK 9 9 OK ・・・ |
1 |
print("{0} / {1} = {2}".format(ng,n_test,1-ng / n_test)) |
1 |
27 / 899 = 0.9699666295884316 |
899件中27件が失敗し正答率は約97%ということが分かります。