機械学習を学んでみたのでそのまとめ⑤Deep Learning

前回に引き続き、Udemy[【世界で74万人が受講】基礎から理解し、Pythonで実装！機械学習26のアルゴリズムを理論と実践を通じてマスターしよう](https://www.udemy.com/course/ml-with-python/)で学んだ内容をアウトプットしていきたいと思います。

(※この記事は勉強した内容のアウトプットを目的としてざっくりと書かれているので、もともと知っていて復習の為に読んだりするにはいいと思いますが、正しく知りたい方は別の記事を読んだほうが良いとおもわれます。コードに関してはライブラリが入っていれば、jupyterなどにコピペすればだいたい動くはずです。)

前回、記事にしたクラスタリングからDeep Learningに至るまで、Association rule learning、強化学習、自然言語処理があったのですが、ここで例題として扱うのに丁度良いデータセットが見つからなかったので、飛ばしてます。今後、手頃なデータセットが見つかればまた取り上げるかもしれません。

## ANN(Artificial Neural Network)

ニューラルネットワーク(ANN)とは脳の神経回路の一部を模した数理モデル(ニューロン)を複数組み合わせたものの総称で、入力層、出力層、隠れ層から構成される。

![qiita_20210616_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350321/7f6edf85-bf2e-56e5-8eb8-d0010a8ed6ef.png)


ニューロン
ニューロンとは複数の入力(下図では2つ)に対し活性化関数を使って演算を行い出力を行うノードのことです。出力をしたニューロンは別のニューロンの入力にもななり得ます。

![qiita_20210616_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350321/80de69c8-4b6e-e0f4-e29e-8e0b8c2ab76b.png)


活性化関数

活性化関数とはニューロンに入って来た入力に対して演算処理をするもので、上記の図の$y = f(x_1w_1+x_2w_2)$の$f()$にあたるもので、代表的なものとしては以下のような種類がある。

・ステップ関数
![qiita_20210619_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350321/9f7a3661-13e8-de46-82c9-1d119c710e63.png)

・シグモイド関数
![qiita_20210619_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350321/7f0ca226-7324-6432-a15d-2e49d4e7267a.png)

・Relu関数
![qiita_20210619_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350321/da499558-3c53-3fba-233d-0dee324e16a7.png)




損失関数
モデルから出力された値と実際の正解を比較してその差を計算する関数で、この差を小さくなるようにする事でモデルを最適化することができます。

モデルからの出力値
$$ y = f(x_1w_1+x_2w_2) $$
正解の値
$$　\hat{y} $$
損失関数
$$　C = 1/2(\hat{y}-y)^2 $$
Cを最小化するように$w_1, w_2$を調整する事でモデルが最適化されます。


勾配降下法
損失関数を$　C = 1/2(\hat{y}-y)^2 $の$C$を最小値を見つけるために、下図のように関数の接線の傾きを小さくしていく事でCの最小値を割り出す方法

![qiita_20210619_6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350321/2bb5068c-207a-f656-632b-d4addcd429ce.png)


とりあえず、ここでも学んだ内容で、分類のときにも使ったScikit-learnのデータセットの乳がん患者を使って、target以外のデータを独立変数、target（悪性or良性）を従属変数としてロジスティック回帰を使った分類をしたいと思います。

ライブラリのインポート

```python
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import tensorflow as tf
from sklearn.datasets import load_breast_cancer
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix, accuracy_score
```

データセットの読み込み

```python
cancer = load_breast_cancer()
cancer_data = pd.DataFrame(cancer.data, columns = cancer.feature_names).assign(malignant=np.array(cancer.target))
X = cancer_data.iloc[:, :-1].values
y = cancer_data.iloc[:, -1].values
```

フィーチャースケーリング

```python
sc = StandardScaler()
X = sc.fit_transform(X)
```

訓練用データセットとテスト用データセットへの分割(8:2)

```python
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 0)
```

ANNの構築

```python
ann = tf.keras.models.Sequential()
ann.add(tf.keras.layers.Dense(units=30, activation='relu'))
ann.add(tf.keras.layers.Dense(units=30, activation='relu'))
ann.add(tf.keras.layers.Dense(units=1, activation='sigmoid'))
ann.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
```

訓練用データセットを使った学習

```python
ann.fit(X_train, y_train, batch_size=32, epochs=50)
```
`出力結果`
Epoch 1/50
15/15 [==============================] - 0s 1ms/step - loss: 0.6230 - accuracy: 0.6901
・・・
（省略）
・・・
Epoch 50/50
15/15 [==============================] - 0s 1ms/step - loss: 0.0156 - accuracy: 0.9978

テスト用データセットを使った結果の予測

```python
y_pred = ann.predict(X_test)
y_pred = (y_pred > 0.5)
print(np.concatenate((y_pred.reshape(len(y_pred),1), y_test.reshape(len(y_test),1)),1))
```
`出力結果`
[[0 0]
 [1 1]
 [1 1]
・・・
（省略）
・・・
 [0 0]
 [0 0]
 [1 1]]

混同行列と精度スコアでモデルの評価

```python
cm = confusion_matrix(y_test, y_pred)
print(cm)
accuracy_score(y_test, y_pred)
```
`出力結果`
[[46  1]
 [ 1 66]]
0.9824561403508771

CNNに関しても講座でならったのですが、ややこしくなるので今回はこのへんで終わります。