手書き文字の画像を認識する

import pandas as pd
# データの読み込み
df = pd.read_csv('./input/mnist.csv.zip')
df.head()
# 1行目のデータをとりだし
d = df.iloc[0, :-1].to_numpy()
# 1行のデータを 28 x 28 の行列に変換してループ
for row in d.reshape([28, 28]):
    # 0のところを '_' 、それ以外(文字が書かれているところ)を '*' で表示
    print("".join("*" if a > 0 else "_" for a in row))
# 説明変数(X)と目的変数(y)の取得
X = df.iloc[:, :-1]
y = df.iloc[:, -1]
from sklearn.model_selection import cross_val_score
import numpy as np
from sklearn.linear_model import LogisticRegression

# C=0.01, 0.1, 1, 10, 100 で試した
lr = LogisticRegression(C=10, random_state=0,
                        solver='liblinear', multi_class='ovr')
scores = cross_val_score(lr, X, y, cv=5)

print("正答率", np.mean(scores), "標準偏差 +/-", np.std(scores))
正答率 0.7450000000000001 標準偏差 +/- 0.05567764362830023
from sklearn.tree import DecisionTreeClassifier

tree = DecisionTreeClassifier(random_state=0)
scores = cross_val_score(tree, X, y, cv=5)

print("正答率", np.mean(scores), "標準偏差 +/-", np.std(scores))
正答率 0.525 標準偏差 +/- 0.047434164902525694
from sklearn.svm import SVC

# C=00.1, 1, 100, gamma=0.1, 1, 100で試した
svm = SVC(C=1, gamma=1, random_state=0)
scores = cross_val_score(svm, X, y, cv=5)

print("正答率", np.mean(scores), "標準偏差 +/-", np.std(scores))
正答率 0.15 標準偏差 +/- 0.0
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(
    X,
    y,
    test_size=0.3,
    random_state=0,
)

# 判定用に変数に保存
clf = lr
clf.fit(X_train, y_train)
clf.score(X_test, y_test)
0.65

今回は画像の画素をそのまま特徴としましたが、大きな画像では次元が大きくなりすぎてしまいます。

画像から顔認識などを使って一部分だけとりだしたり、LBPなどの手法で特徴抽出することで次元を減らせます。
こうすることでより少ないリソースで精度の高い分類ができるようになります。

ディープラーニングはこういった事前の特徴抽出の処理が不要なので、現在注目されています。

コメント

タイトルとURLをコピーしました