サポートベクタマシン（load_iris）

今回はサポートベクタマシン（分類）の実装をまとめていきます。

※以降、SVMと省略することがあります。

##■ サポートベクタマシンの手順

次の7つのSTEPで進めます。

1. モジュールの用意
2. データの準備
3. データの可視化
4. モデルの作成
5. モデルのプロット
6. 分類を予測
7. モデルの評価
<br>

##1. モジュールの用意
最初に、必要なモジュールをインポートしておきます。

```python

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

# データセットを読み込むモジュール
from sklearn.datasets import load_iris

# 標準化（分散正規化）を行うモジュール
from sklearn.preprocessing import StandardScaler

# 訓練データとテストデータを分割するモジュール
from sklearn.model_selection import train_test_split

# サポートベクトルマシンを実行するモジュール
from sklearn.svm import SVC

# 分類の評価を行うモジュール
from sklearn.metrics import classification_report
```
<br>

##2. データの準備
今回はirisデータセットを使って、二値分類をしていきます。

最初にデータの取得をし、標準化を行ってから分割します。

```python

# irisデータセットの読み込み
iris = load_iris()

# 目的変数と説明変数に分ける
X, y = iris.data[:100, [0, 2]], iris.target[:100]

# 標準化（分散正規化）
std = StandardScaler()
X = std.fit_transform(X)

# 訓練データとテストデータに分割する
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)
```
二値分類を行うために、データセットを100行目まで（Setosa・Versicolor のみ）と指定しています。
またプロットしやすくするために、説明変数も2つに絞っています。（Sepal Length・Petal Lengh のみ）

標準化は、例えば2桁と4桁の特徴量（説明変数）があった際に、後者の影響が大きくなってしまうため
全ての特徴量に対して平均を0・分散を1にして、スケールを揃えています。
<br>
##3. データの可視化
SVMで分類をする前のデータをプロットして見ておきます。

```python

# 描画オブジェクトとサブプロットの作成
fig, ax = plt.subplots()

# Setosa のプロット
ax.scatter(X_train[y_train == 0, 0], X_train[y_train == 0, 1], 
           marker = 'o', label = 'Setosa')

# Versicolor のプロット
ax.scatter(X_train[y_train == 1, 0], X_train[y_train == 1, 1],
           marker = 'x', label = 'Versicolor')

# 軸ラベルの設定
ax.set_xlabel('Sepal Length')
ax.set_ylabel('Petal Length')

# 凡例の設定 
ax.legend(loc = 'best')

plt.show()
```
Setosa (y_train ==0) に対応する特徴量（0：Sepal Lengh を横軸, 1: Petal Length を縦軸）でプロット
Versicolor (y_train ==1) に対応する特徴量（0：Sepal Lengh を横軸, 1: Petal Length を縦軸）でプロット

＜出力結果＞
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/725082/f811cb02-8080-a41e-26c2-35802e08d47b.png)
##4. モデルの作成
最初にSVMの実行関数（インスタンス）を作成し、訓練データに当てはめます。

```python

# インスタンスを作成
svc = SVC(kernel = 'linear', C = 1e6)
    
# 訓練データからモデルを作成
svc.fit(X_train, y_train)
```
今回はすでに線形分離（1本の直線で分ける）が可能なので、引数を kernel = 'linear' に設定しています。

また C はハイパーパラメータで、出力数値やプロットを見ながら自身で調整していくものです。
<br>
##5. モデルのプロット
訓練データからサポートベクタマシンのモデルが作成できたので
どのように分類ができているのか、プロットして確認します。

前半は、先ほどの散布図のコードと全く同じです。

```python

# 描画オブジェクトとサブプロットの作成
fig, ax = plt.subplots()

# Setosa のプロット
ax.scatter(X_train[y_train == 0, 0], X_train[y_train == 0, 1], 
           marker = 'o', label = 'Setosa')

# Versicolor のプロット
ax.scatter(X_train[y_train == 1, 0], X_train[y_train == 1, 1],
           marker = 'x', label = 'Versicolor')

ax.set_xlabel('Sepal Length')
ax.set_ylabel('Petal Length')
    
ax.legend(loc = 'upper left')

# ここから下は、他データの場合でもそのままペーストして毎回流用できます。（数値の微調整は必要）

# 決定境界（直線）のプロット範囲を指定
xmin = -2.0
xmax = 2.5
ymin = -1.5
ymax = 1.8

# 決定境界とマージンをプロット
xx, yy = np.meshgrid(np.linspace(xmin, xmax, 100), np.linspace(ymin, ymax, 100))
xy = np.vstack([xx.ravel(), yy.ravel()]).T
p = svc.decision_function(xy).reshape(100, 100)  
ax.contour(xx, yy, p, colors = 'k', levels = [-1, 0, 1], alpha = 1, 
           linestyles = ['--', '-', '--'])

# サポートベクタをプロット
ax.scatter(svc.support_vectors_[:, 0], svc.support_vectors_[:, 1],
           s = 250, facecolors = 'none', edgecolors = 'black')
    
plt.show()
```
alpha：直線の濃さ
s：サポートベクタ（○）の大きさ

＜出力結果＞
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/725082/72ddc5ca-4bf2-459f-cccb-921818b746d5.png)
##6. 分類を予測
モデルが完成したので、分類の予測をしていきます。

```python
# 分類結果を予測する
y_pred = svc.predict(X_test)

# 予測値と正解値を出力
print(y_pred)
print(y_test)
```
＜出力結果＞

```python

# 予測値と正解値を比較してみる
y_pred: [0 1 1 1 0 0 1 0 1 0 0 1 0 0 0 0 0 0 1 1 1 0 0 1 0 0 1 1 1 1]
y_test: [0 1 1 1 0 0 1 0 1 0 0 1 0 0 0 0 0 0 1 1 1 0 0 1 0 0 1 1 1 1]
```
0：Setosa　1：Versicolor

今回の場合は全て一致（正解）していることが分かります。
<br>
##7. モデルの評価
今回は分類（二値分類）となるので、混同行列を用いた適合率・再現率・F値で評価を行います。

```python

# 適合率、再現率、F値を出力
print(classification_report(y_test, y_pred))
```
＜出力結果＞
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/725082/bc565453-223c-f9ce-3da7-af252b50920a.png)

以上より、Setosa と Versicolor における分類の評価を行うことができました。
<br>
##■ 最後に
SVMでは上記1～7の手順をもとに、モデルの作成・評価を行っていきます。

今回は初学者の方向けに、実装（コード）のみまとめさせていただきましたが
今後タイミングを見て、理論（数式）についても記事を作成していければと思います。

ご精読いただき、ありがとうございました。

参考文献：[Pythonによるあたらしいデータ分析の教科書](https://www.shoeisha.co.jp/book/detail/9784798158341)
　　　　（Python 3 エンジニア認定データ分析試験　主教材）