■手書きの数字画像を表示
datasets.load_digits() で手書き数字のデータを参照できる。
digits.images ... 画像データの配列
digits.target ... データがどの数字を表すかのラベル
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
# 手書きデータを読み込む
from sklearn import datasets
digits = datasets.load_digits()
# 15個連続で出力する
for i in range(15):
plt.subplot(3, 5, i+1) # 3行×5列の枠組みを用意し、i+1番目に表示する
plt.axis("off") # 軸線を表示しない
plt.title(str(digits.target[i])) # 見出し文字
plt.imshow(digits.images[i], cmap="gray") # 画像をグレースケールで表示する
# 画像に保存する
plt.savefig("output.png")
■手書きの数字を学習&判定
以下で学習させる。
from sklearn.model_selection import train_test_split
from sklearn import datasets, svm, metrics
from sklearn.metrics import accuracy_score
#from sklearn.externals import joblib
import joblib
# データを読み込む
digits = datasets.load_digits()
x = digits.images
y = digits.target
x = x.reshape((-1, 64)) # 二次元配列を一次元配列に変換
# データを学習用とテスト用に分割する
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2)
# データを学習
clf = svm.LinearSVC()
clf.fit(x_train, y_train)
# 予測して精度を確認する
y_pred = clf.predict(x_test)
print(accuracy_score(y_test, y_pred))
# 学習済みデータを保存
joblib.dump(clf, "digits.pkl")
以下で判定させる。
手書きの画像を number フォルダ内に 0.png 〜 9.png の名前で保存しておく。
ただし自分の手書き文字で試すと正解率は50%程度。
ディープラーニングを用いた方法の方が制度が高くなるらしいので、引き続き要勉強。
import cv2
#from sklearn.externals import joblib
import joblib
def predict_digit(filename):
# 学習済みデータを読み込む
clf = joblib.load("digits.pkl")
# 自分で用意した手書きの画像ファイルを読み込む
my_img = cv2.imread(filename)
# 画像データを学習済みデータに合わせる
my_img = cv2.cvtColor(my_img, cv2.COLOR_BGR2GRAY)
my_img = cv2.resize(my_img, (8, 8))
my_img = 15 - my_img // 16 # 白黒反転する
# 二次元を一次元に変換
my_img = my_img.reshape((-1, 64))
# データ予測する
res = clf.predict(my_img)
return res[0]
# 画像ファイルを指定して実行
for i in range(10):
n = predict_digit("number/" + str(i) + ".png")
print("my" + str(i) + ".png = " + str(n))