MNIST(8x8 pixels)を使ったモデル精度考察

# 概要
MNIST(8x8 pixels)のデータセットを使って、
RandomForest分類器の他に２種類、分類器を用意して学習させ、
それぞれの学習済みモデルの精度を比較し、
文字認識の観点から精度や モデルが予測する結果について考察する。
評価対象はaccuracy_scoreとconfusion_matrixとします。

# 文字認識等について調査
文字認識について調べる
参考URLhttps://office54.net/python/ai/machine-learning-method

①ランダムフォレストhttps://scikit-learn.org/stable/modules/generated/sklearn.ensemble.RandomForestClassifier.html
・それぞれ異なったグループで学習をし、いくつかの決定木を作り、平均・多数決するhttps://qiita.com/Hawaii/items/5831e667723b66b46fba
・ランダム性（それぞれ異なるデータを基にする、異なる説明変数を分割候補として使う）https://mathwords.net/randomforest
https://qiita.com/mshinoda88/items/8bfe0b540b35437296bd

②ロジスティクス回帰
・特徴量空間が線形分離可能な場合のみに高い性能を発揮する

・特徴量空間
説明変数がある空間
・特徴量
データのどのような特徴に着目すべきか
分析対象データの中の予測の手掛かりとなる変数
Excelなどの一つの列が特徴量になる

特徴量空間とは目的変数を説明するためのデータが存在する空間のことを言います。 目的変数のとある１点は説明変数の特徴量空間の次元のそれぞれ１点の結果として現れるものであり、 特徴量空間の１点と目的変数の１点はつながっているものと考えるのがポイントです。

今回の画像で言えば、64次元の各次元（各ピクセル）のそれぞれの値（色味：グレースケールならば8bitで0-255階調）のもと、 人間が認識できる文字（目的変数の値）と紐づくと考えます。

ベクトルとは、特徴量空間の各次元の１点を集約して表現したものであり、 データセット言えば行に相当するものです。

まとめると（繰り返しにはなりますが）、目的変数の点が64次元の数値で表され、各次元に存在する数値の組み合わせがベクトルであり、 そのベクトルがあるときに目的変数である人間が認識できる数値情報と紐づくと考えばＯＫです。

参考URLhttps://qiita.com/0NE_shoT_/items/b702ab482466df6e5569

線形分離可能
https://qiita.com/forusufia/items/53de18be0e07b258fc76
https://pictblog.com/ai-bunrui-9

のちに調べて分かったhttps://aidemy.net/magazine/655/

③K近傍法（ケイきんぼうほう）
https://toukei-lab.com/%EF%BD%8B%E8%BF%91%E5%82%8D%E6%B3%95

# 実装
ライブラリの読み込み
```python
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import load_digits

%matplotlib inline

from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score, confusion_matrix
import seaborn as sns
```

MNISTの読み込みとデータ操作、加工
```python
mnist = load_digits()
mnist.keys()
```
dict_keys(['data', 'target', 'frame', 'feature_names', 'target_names', 'images', 'DESCR'])
```python
x = mnist["data"]
y = mnist["target"]
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2)
```

# 学習と検証
今回検証することは「どのモデルが安定した精度を出せるか」ということです。
今回は以下のモデルを作成します

①.ランダムフォレスト
+ パラメータなし：3つのモデル
```python
RandomForestClassifier()
```
②ロジスティクス回帰
+ max_iter=5000
```python
LogisticRegression(max_iter=5000)
```

③K近傍法
+ 指定無し（n_neighbors=5）
+ n_neighbors = 2
+ n_neighbors = 10
```python
KNeighborsClassifier()
KNeighborsClassifier(n_neighbors = 2)
KNeighborsClassifier(n_neighbors = 10)
```

詳細なソースコード
https://github.com/haru-cpu/ai_learn/blob/main/Homework_01.ipynb
# 結果
![Screenshot 2024-09-03 105327.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955266/49db8460-63c8-4053-2883-6f831c70d544.png)
３つのアルゴリズムも 0.9 以上と高い数値を出している。
ロジスティクス回帰に関しては、他２つと比べて少し低い数値となっている。

**【混同行列】**

**ランダムフォレスト1つ目**
![Screenshot 2024-09-03 105447.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955266/ce28f39a-2b68-07de-f326-be346e740184.png)

**ランダムフォレスト2つ目**
![Screenshot 2024-09-03 105502.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955266/b6192062-98ef-9cd0-4606-c4afba38bbc9.png)

**ランダムフォレスト3つ目**
![Screenshot 2024-09-03 105514.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955266/2d08005d-25cf-9a14-c9ab-a1af608ab071.png)

ランダムフォレストに関しては、説明変数がランダムに採用されるため、
３つのモデルで学習をさせた。
最も注目する FP の値に関しては、３つのランダムフォレストのモデルと差はほとんど見ら
れず、安定している。
それに比べ、FP ほど重要視はしていないが、
FN に関しては、FP と比べて差が大きいことがわかる。

**ロジスティック回帰**
![Screenshot 2024-09-03 105937.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955266/21d5afaa-1fd0-e32c-0235-bc566c3c48cc.png)

ロジスティック回帰に関しては、
ランダムフォレストのモデルと次で見る k 近傍法と比べると、
FN、FP の値が大きく、精度の良いモデルとはいえない。

**K 近傍法（n_neighborns = 5）**
![Screenshot 2024-09-03 110300.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955266/ea49d925-3838-0dd6-320e-38224b540655.png)

**K 近傍法（n_neighborns = 2）**
![Screenshot 2024-09-03 110310.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955266/025e6eeb-95a6-f700-3b18-20a928fc37af.png)

**K 近傍法（n_neighborns = 10）**
![Screenshot 2024-09-03 110318.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955266/2525694a-31b2-3ebd-43a7-afd2eaeee8f7.png)

モデルの差を測るため、n_neighbors の値を変更して、3 つのモデルの作成をしている。
FP、FN に関しては、値が一番大きい３つ目のモデルが一番良い評価となった。
これは、n_neighbors の値を大きくしたことによって、
参考にするデータが増え、精度が高くなったと考えられる。
しかし、n_neighbors の値を大きくしすぎてしまうと、参考にするデータの範囲が広がりす
ぎてしまい、精度が落ちる危険性がある。

# 考察
精度が一番良いモデルは、「k 近傍法」である。
理由としては、以下 2 つ。
**① FP、FN の値が最も小さい**
**② モデルを作成する際に詳細な設定でモデルを安定させることができる**

**① について**
FP が小さいければ良いと理由は、本来では NG であるモノを許可してしまうことによって、
企業評価が下がってしまう危険性がある。
例えば、不良品が市場に出回ることによって、顧客に被害を与えてしまう恐れがある。
そのため、TP, TN, FP, FN の中でも、最も重要視しなければならない。
また、FN に関しては、本来であれば OK であったものを拒否してしまうことにより、機会損失をしてしまっていると考えられる。
顧客に被害を与えるまではいかなくとも、企業の成長を止めているということになるため、重要視したい値である。
今回のモデルに関していえば、ランダムフォレストと k 近傍法が最も小さな値を出している。

**② について**
ランダムフォレストは、説明変数がランダムに採用されるため、
同じ条件（ハイパーパラメータの値が同じ）であったとしても、異なる結果が出る。
そのため、モデルの精度としては高い数値を出しているが、k 近傍法と比べてしまうと不安定なモデルといえる。
また、ロジスティック回帰の精度が低かった理由としては、線形分離可能性が低かったことであると考える。
文字認識は画像のピクセルの明暗を値化し、モデルに学習させている。
しかし、文字は独立的な値の集まりではなく、連続的な値のため、ロジスティック回帰には適していない。

【追加での考察】
**Ｑ独立的な値の集まりではない…の部分について**
・文字認識
　→独立した値ではなく、連続した値。
・独立した値
　→1 つの値で完結する、理解できる値
 
・連続した値（連続した値という言い方が合っているかわかりません。。。）
　→1 つの値では意味を表せない値
 　→複数の値を組み合わせることで、ある意味を表現できる
  
・文字認識
　→画像をピクセル単位で区切り、その一つのピクセルの色を値化し、その画像の構造（8×8）を全て 1 列にして、値から文字を認識する。
 →画像（文字）は、１つの画像を１つの説明変数によって表しているのではなく、ピクセル数分の色の値が連なった状態(=値が連続している）で表している

・ロジスティック回帰
　→特徴量空間が線形分離可能な場合に高い精度を出す。
文字認識
→線形分離可能ではない
 →【理由①】文字認識は、独立的な値の集合ではなく、連続的な値の集合だから
 →上記の文字認識の説明
 →【理由②】sns.pairplot()で確認済み
 →もしも線形分離可能な場合であれば、目的変数ごとに色がはっきりと分かれる
 →しかし、文字認識は色がバラバラに表現され、
 １本の線で区切ることのできる箇所は存在しなかった
 
⇒文字認識ではロジステック回帰の特性を活かすことができない