【機械学習】手書き文字データで分類器のパフォーマンスチェックをしてみる

こんにちは。
林@[アイエンター](http://www.i-enter.co.jp)です。

前回の[ブログ](http://qiita.com/m-hayashi/items/519c75653e517c15f51b)では、scikit-learnのk平均法アルゴリズムとOpenCVを用いて、画像の減色処理を行いました。

今回は、scikit-learnに用意されている、手書き文字データのサンプルを用いて
複数の分類器の簡単なパフォーマンスチェックを行ってみます。

# 手書き文字データの読み込み
scikit-learnのdatasetsには、手書き文字データのサンプルが用意されていますので、それを読み込みます。
![shot1.png](https://qiita-image-store.s3.amazonaws.com/0/134453/52fe7ce8-e262-bd04-c8bd-1a1493457423.png)

説明変数Xが0〜9のイメージデータの配列、目的変数Yが各イメージに対応する0〜9の数字の配列になっています。

Xデータの先頭データはこのような64個の数値配列になっています。
![shot2.png](https://qiita-image-store.s3.amazonaws.com/0/134453/8baf9ef1-a8f3-f177-fc4f-c48c8cab0cbf.png)

実際はこの配列は、画像としては8×8のサイズのイメージデータなので、
配列を加工して、先頭の20個のデータを表示してみます。
イメージはグレースケールのピクセル画像で表示します。

![shot3.png](https://qiita-image-store.s3.amazonaws.com/0/134453/4fcaaa80-5220-6840-4640-2d583f770e2a.png)

# K-fold交差検証
今回、分類器の精度を「K-fold交差検証」を用いて評価します。
「K-fold交差検証」とは、標本群をK個のブロックに分割して、K-1個のブロックを訓練データ、残りの1ブロックをテストデータとして評価します。
また、テスト用のブロックも1番目からK番目に切り替えながら評価していきます。
以下のようなイメージです。
![shot4.png](https://qiita-image-store.s3.amazonaws.com/0/134453/91507a42-74eb-d0a6-9bfb-e68639fda065.png)
scikit-learnではcross_validationにK-foldが用意されています。
今回は、標本データを10分割するK-foldを用意します。
![shot5.png](https://qiita-image-store.s3.amazonaws.com/0/134453/e0cb1d51-f96a-87bb-e1ba-485129fa5587.png)

# 評価する分類器
以下の分類器をパフォーマンスチェックします。
[LogisticRegression](http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html)（[ロジスティック回帰](https://ja.wikipedia.org/wiki/ロジスティック回帰)）
[GaussianNB](http://scikit-learn.org/stable/modules/naive_bayes.html)（[ナイーブベイズ](https://ja.wikipedia.org/wiki/単純ベイズ分類器)）
[SVC](http://scikit-learn.org/stable/modules/generated/sklearn.svm.SVC.html)（[サポートベクターマシン](https://ja.wikipedia.org/wiki/サポートベクターマシン)）
[DecisionTreeClassifier](http://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html)（[決定木](https://ja.wikipedia.org/wiki/決定木)）
[RandomForestClassifier](http://scikit-learn.org/stable/modules/generated/sklearn.ensemble.RandomForestClassifier.html)（[ランダムフォレスト](https://ja.wikipedia.org/wiki/ランダムフォレスト)）
[AdaBoostClassifier](http://scikit-learn.org/stable/modules/generated/sklearn.ensemble.AdaBoostClassifier.html)（[AdaBoost](https://ja.wikipedia.org/wiki/AdaBoost)）
[KNeighborsClassifier](http://scikit-learn.org/stable/modules/generated/sklearn.neighbors.KNeighborsClassifier.html)（[K近傍法](https://ja.wikipedia.org/wiki/K近傍法)）

また、SVCについては、カーネルの種類を「rbf（ガウシアンカーネル）」「linear（線形カーネル）」「poly（多項式カーネル）」の3種類で確認します。

以下のような分類器インスタンスと名前を要素とする配列を用意します。
![shot6.png](https://qiita-image-store.s3.amazonaws.com/0/134453/663a7d65-f47a-78b7-f82a-b6c6cf6c7f7b.png)

#パフォーマンスチェックについて
パフォーマンスチェックは、各分類器の精度と解析スピードで評価します。
精度については、K-foldでの10回の予測テストを、sklearn.metricsのaccuracy_scoreで、スコアリングして平均を取ります。
また、解析スピードは、学習（fit）から予測(predict)にかかる時間を計測して
平均を取ります。
![shot7.png](https://qiita-image-store.s3.amazonaws.com/0/134453/af91e415-f648-da64-1e64-60c0f7e4639b.png)

以下のような結果が出力されました。
![shot8.png](https://qiita-image-store.s3.amazonaws.com/0/134453/09d1ef62-fe5d-8b04-1de2-6fdb7b8476b7.png)

精度的に良い数値が出ているのが、3種類カーネルの「SVC」（サポートベクターマシン）と「KNeighborsClassifier」（K-近傍法）の分類器です。

最も高い精度は、SVC-rbfですが、解析時間もそれなりにかかっているようです。
KNeighborsClassifierは精度的には2番目の数値ですが、解析スピードはSVC-rbfの4倍のスピードが出ています。

精度とスピードを総合的に評価すると、K-近傍法（KNeighborsClassifier）の分類器が、このテストでは最も高いパフォーマンスの分類器と言えるかと思います。

今回のお話はここまで！