機械学習はどんなふうに分類しているか

機械学習の分類と一言で言っても色々な分類へのアプローチがあります。
そこで、縦横0から1までを細かくデータにして分類をどのようにしているか可視化してみます。
# 関数
```Python3
from sklearn import preprocessing
import matplotlib.pyplot as plt
import numpy as np
def showline_clf(x, y, model, modelname, x0="x0", x1="x1"):
    fig, ax = plt.subplots(figsize=(8, 6))
    X, Y = np.meshgrid(np.linspace(*ax.get_xlim(), 1000), np.linspace(*ax.get_ylim(), 1000))
    XY = np.column_stack([X.ravel(), Y.ravel()])
    x = preprocessing.minmax_scale(x)
    model.fit(x, y)
    Z = model.predict(XY).reshape(X.shape)
    plt.contourf(X, Y, Z, alpha=0.1, cmap="brg")
    plt.scatter(x[:, 0], x[:, 1], c=y, cmap="brg")
    plt.xlim(min(x[:, 0]), max(x[:, 0]))
    plt.ylim(min(x[:, 1]), max(x[:, 1]))
    plt.title(modelname)
    plt.colorbar()
    plt.xlabel(x0)
    plt.ylabel(x1)
    plt.show()
```
# プログラム
## ライブラリのインポート
```Python3
from sklearn.datasets import make_blobs
from sklearn.svm import SVC
from sklearn.ensemble import RandomForestClassifier as RFC
from sklearn.ensemble import GradientBoostingClassifier as GBC
from sklearn.tree import DecisionTreeClassifier as DTC
from sklearn.linear_model import LogisticRegression as LR
from sklearn.neighbors import KNeighborsClassifier as KNN
import matplotlib.pyplot as plt
```
## データセットの可視化
```Python3
x, y = make_blobs(n_samples=300, centers=4, random_state=0, cluster_std=1.0)
plt.scatter(x[:, 0], x[:, 1], c=y, cmap="brg")
plt.show()
```
![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/448cc320-602e-d896-6e32-6db0969a43a1.png)

## 各機械学習モデル
```Python3
model1 = SVC()
model2 = SVC(kernel="linear")
model3 = DTC()
model4 = RFC()
model5 = GBC()
model6 = LR()
model7 = KNN()
```

## SVM(RBF)
分類データの次元を上げて分類できるようにしてから分類し、元に戻す手法でガウス関数を使います。
```Python3
model1.fit(x, y)
showline_clf(x, y, model1, "SVM RBF kernel", x0="x0", x1="x1")
```
![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/4b6bbb6d-1db2-d7ab-fd11-05b76774c572.png)

## SVM
分類曲線と平行に支持曲線を作り、その支持曲線と支持曲線の間が最大になるように分類します。
```Python3
model2.fit(x, y)
showline_clf(x, y, model2, "SVM", x0="x0", x1="x1")
```
![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/45c61b81-bba4-5060-891f-ac7b6ad760d1.png)

## 決定木
各変数ごとにif文でその値より高いか低いかで分類していくアルゴリズムです。そのため縦線と横線のみになります。
```Python3
model3.fit(x, y)
showline_clf(x, y, model3, "DecistionTree", x0="x0", x1="x1")
```
![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/a8e1a6f4-9851-34db-eb9f-c90719e7db60.png)

## ランダムフォレスト
決定木を複数作ってバギングという謂わば多数決を使って分類精度を上げるという手法です。少し曲線っぽく見えますが、よく見ると決定木同様縦横線だけです。
```Python3
model4.fit(x, y)
showline_clf(x, y, model4, "RandomForest", x0="x0", x1="x1")
```
![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/f6d21132-191a-9aad-4137-7b900066513e.png)

## 勾配ブースティング決定木
決定木の深さを浅くした状態でより良いクラスごとの決定木を作っていき、Softmax関数で分類していきます。そのためアンサンブル学習ですがランダムフォレストと異なり決定木と似たようになります。
```Python3
model5.fit(x, y)
showline_clf(x, y, model5, "GBDT", x0="x0", x1="x1")
```
![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/ab3c2b3d-9519-5a04-d0fc-b3b61aaa9b48.png)

## ロジスティック回帰
シグモイド関数を多変量にして分類しています。
```Python3
model6.fit(x, y)
showline_clf(x, y, model6, "LogisticRegression", x0="x0", x1="x1")
```
![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/e05cc834-543e-f9d1-fd33-895441c05589.png)



## K-近傍法
未知のデータがどの正解データに距離的に近いかを多数決で分類していくアルゴリズムです。k-NNのkはその多数決の数になります。
```Python3
model7.fit(x, y)
showline_clf(x, y, model7, "K-NN", x0="x0", x1="x1")
```
![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/8cb77f2a-7bed-e104-68a4-cd9a1e253b6f.png)

## ナイーブベイズ
```Python3
model11 = GaussianNB()
model11.fit(x, y)
showline_clf(x, y, model11, "Naive Bayse", x0="x0", x1="x1")
```
![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/1cef7048-de7d-9d90-0c3d-623fb9630a30.png)



# 余談
## クラスタリング
### K-means法
```Python3
from sklearn.cluster import KMeans
model10 = KMeans(n_clusters=4)
model10.fit_predict(x)
showline_clf(x, y, model10, "MLP", x0="x0", x1="x1")
```
![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/1abc5f68-690b-b7ef-a649-89a232c3b803.png)
直線になるんですね・・・

## 異常検知アルゴリズム
マップの色が青が異常値で緑が正常値です。
### IsolationForest
```Python3
from sklearn.ensemble import IsolationForest
model8 = IsolationForest()
model8.fit(x)
showline_clf(x, y, model8, "IsolationForest", x0="x0", x1="x1")
```
![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/9f245b57-93d5-af5d-0757-8fc27da50cad.png)

### OneClassSVM
```Python3
from sklearn.svm import OneClassSVM
model9 = OneClassSVM()
model9.fit(x)
showline_clf(x, y, model9, "OneClassSVM", x0="x0", x1="x1")
```
![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/d61171ac-2ad5-3d8e-e160-f0d88930d3e5.png)

## LightGBM
Scikit-LearnにはGradientBoostingClassifierがありますが、それより速く動く勾配ブースティング決定木です。
```Python3
from lightgbm import LGBMClassifier
model11 = LGBMClassifier()
model11.fit(x, y)
showline_clf(x, y, model11, "LightGBM", x0="x0", x1="x1")
```
![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/580355a0-a669-300b-c748-dde6cced8be1.png)


# まとめ
性質ごとに使い分けをしましょう。