【初心者】機械学習のクラスタリング（エルボー法）を調べてみた

# 背景・目的
私は、現在データエンジニアリングを生業としています。普段は、データ基盤の構築や、パフォーマンスチューニングなどビックデータに関する業務に従事しています。
ビックデータの収集や、蓄積、分析などの環境構築の経験はそこそこありますが、機械学習による予測や分類などのスキルは持ち合わせていませんでした。
今まで機械学習を避け続けてきましたが、一念発起し学ぼうと思います。

学び方としては、AWS Certified Machine Learning – Specialty（以降、ML試験という。）の勉強を通して、理解を深めていきます。ML試験のガイドの第２分野に、探索的データ解析が登場しましたのでそこから学びたいと思います。

今回は、**クラスタリングのエルボー法**について学びたいと思います。

> 2.3 機械学習のデータを分析および視覚化する
> ・クラスタリング (階層型、診断、エルボープロット、クラスターサイズ

なお、過去の機械学習の調べてみたシリースは下記にまとめています。
- 2.探索的データ分析
- 2.1.モデリング用のデータをサニタイズおよび準備する
    - [【初心者】探索的データ解析とは何かを調べてみた](https://qiita.com/zumax/items/52c97307bf18f407bb6e)
    - [【初心者】データのスケーリングを調べてみた](https://qiita.com/zumax/items/ca7184dcf4e7fd242128)
    - [【初心者】データの拡張を調べてみた](https://qiita.com/zumax/items/0727e329f3322897d3e7)
    - [【初心者】データアノテーションを調べてみた](https://qiita.com/zumax/items/d0da86b68b05b99cb23e)
- 2.2.特徴エンジニアリングを実行する
    - [【初心者】特徴量エンジニアリングについて調べてみた](https://qiita.com/zumax/items/3b6e771ef1fcaf3edd91)
    - [【初心者】特徴量エンジニアリング（データのビニング）について調べてみた](https://qiita.com/zumax/items/dc0c86736dd5362cf118)
    - [【初心者】特徴量エンジニアリング（トークナイゼーション）について調べてみた。](https://qiita.com/zumax/items/5286c51ecc0a81b66b87)
    - [【初心者】特徴量エンジニアリング（外れ値）について調べてみた](https://qiita.com/zumax/items/2a07f6d3502fc9a16a44)
    - [【初心者】特徴量エンジニアリング（合成データ）について調べてみた](https://qiita.com/zumax/items/654eae53dae77f222433)
    - [【初心者】特徴量エンジニアリング（ダミー変数[One-Hotエンコーディング]）について調べてみた](https://qiita.com/zumax/items/de5cef1ac4a281400764)
    - [【初心者】特徴量エンジニアリング（次元低減）について調べてみた](https://qiita.com/zumax/items/d92342c3da94020eedec)
- 2.3 機械学習のデータを分析および視覚化する
    - [【初心者】機械学習のデータを分析および視覚化を調べてみた](https://qiita.com/zumax/items/1879441180372858d006)
    - [【初心者】機械学習のクラスタリングを調べてみた](https://qiita.com/zumax/items/41f1366f4f1a00eee1f0)
- 機械学習プロセス
    - [【初心者】AWS Machine Learning Lensを整理する](https://qiita.com/zumax/items/93f9635b3be51fe483e1)

# まとめ
エルボープロットにより、急激に変わる箇所を可視化し最適なクラスタ数を見つける。

# 概要
## エルボー法とは？
クラスタの数に応じて、SSEを計算しグラフ化し、その形状から最適なクラスタ数を選択する手法です。
## SSEとは？
Sum of Squared errors of predictionの略。クラスタ内誤差平方和と呼ばれるもの。
各クラスタの重心から、各点までの距離の総和のように考えておけばよい。

グラフを見ながら、SSEとクラスタ数がなるべく小さくなる組み合わせを見つける。
グラフでみると、急激に変わるところがある。このポイントが最適なクラスタ数となる。

# 実践
こちらの記事「[エルボー法とは , サンプルデータへの適用例](https://ikuty.com/2019/07/24/elbow_method/)」を参考に、手を動かします。ありがとうございます。

## ライブラリのインポート
```
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
```

## 散布図でデータを確認
```
mu = [[0,0], [20,20], [50,50], [40,30], [40,10], [20,40]]
sigma = [ [[30,20],[20,50]],  [[20,30],[10,20]],  [[60,40],[20,20]], [[60,20],[20,60]] ,[[30,10],[10,30]],[[50,20],[20,50]]  ]
points = 100
clusters = []
 
for index in range(len(mu)):
    cluster = np.random.multivariate_normal(mu[index], sigma[index], points)
    dig = np.full((points,1),index+1, dtype=int)
    cluster = np.hstack((cluster,dig))
    clusters = np.r_[clusters,cluster] if len(clusters) > 0 else cluster
 
plt.scatter(x=clusters[:,0], y=clusters[:,1],c=clusters[:,2])

```

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/8286edf5-928e-cc75-2678-f4131063a150.png">


```
kmeans_model = KMeans(n_clusters=6, init='random',max_iter=10).fit(clusters[:,:2])
labels = kmeans_model.labels_

distortions = []
numClusters = 10

for i in range(1,numClusters):
    kmeans_model = KMeans(n_clusters=i, init='random',max_iter=10)
    kmeans_model.fit(clusters[:,:2])
    distortions.append(kmeans_model.inertia_)
        
plt.plot(range(1,numClusters),distortions,marker='o')
plt.xlabel('Number of clusters')
plt.ylabel('Distortion')
plt.show()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/7ef26f66-578a-3f33-8032-4208b77dacc0.png)

- ４〜6あたりでサチっています。

# 考察
今回は、エルボー法（エルボープロット）について試してみました。クラスタ数を決める方法では他にもシルエット分析などがあるようです。

# 参考
https://pictblog.com/ai-class-3

https://ikuty.com/2019/07/24/elbow_method/