自己組織化マップ(SOM)でポケモンをクラスタリング(その2)

https://qiita.com/yellow_detteiu/items/188adfad688c79716b67?utm_campaign=post_article&utm_medium=twitter&utm_source=twitter_share

こちらの記事の続きです。
自己組織化マップ(SOM)というクラスタリングの手法を使って、今度は私の好きな水ポケモンについてマッピングしてみました。はたして、多種多様な水タイプの生態系はどのようになっているのでしょうか。

# 自己組織化マップ(SOM)について

この辺りの記事が参考になります。  

[子供でもわかる「自己組織化マップ」](http://gaya.jp/spiking_neuron/som.htm)  
[自己組織化マップ入門](http://www.brain.kyutech.ac.jp/~furukawa/data/SOMtext.pdf)  

分析したいデータを2次元のマップに写像して、マップの中の色である程度クラス分けができる、という手法です。各データ(Xn)に最も近いデータとその周辺のデータを、だんだんXnに近づくよう学習させて、最終的にいくつかのグループに分かれるようにする手法です。

# ライブラリsomocluについて

こちらの記事 https://www.haya-programming.com/entry/2018/04/07/161249  
で紹介されていた、somocluというPythonのライブラリを使ってみました。  

必要なコード数が少なく、付けられるオプションも豊富なので、割と使いやすかったです。でも、ネット情報が少ないので、細かい調整はしづらかったです。

# 分析

### 使用データ
https://smart-hint.com/poke-data/introduction/
こちらから拝借しました。PokeAPIというものを使って取得されているようです。

### 使用環境
・Windows10
・Google Colaboratory

### コード

前回と大体同じです。今回はデータを水タイプに絞ってモデルを作成しました。そのために変更の必要が出たところは一部修正しました。

データフレームの作成
```Python
df_water = df_pokemon.query('タイプ1 == "みず" or タイプ2 == "みず"')
df_water
```

モデルの作成
```Python
X = df_water.drop(['id', '名前', '画像URL'], axis=1)
X = pd.get_dummies(X)
y = df_water['名前']
   
# SOMに入れる前にPCA(主成分分析)して計算コスト削減を測る 
pca = PCA(n_components=5) 
X = pca.fit_transform(X)

# SOMの定義
n_rows = 16
n_cols = 24
som = Somoclu(n_rows=n_rows, n_columns=n_cols,
              initialization="pca", verbose=2, compactsupport=False)
```

モデルの学習
```Python
# 学習

%%time
som.train(data=X, epochs=1000)
```

今回は10秒くらいで終わりました。

結果の可視化

```Python
# U-matrixをファイル出力

%%time
som.view_umatrix(figsize=(24, 16), labels=y.values, bestmatches=True,
                  filename="umatrix.png")
```

![water1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2475646/794968f1-9ca2-bfc4-d826-99b1f3c29595.png)

ちゃんとホエルオー、ホエルコ、ヨワシ辺りが異端となっていることから、ある程度上手くマッピングできているようです。耐久の高いドヒドイデ、攻撃力の高いシザリガーなども割と孤高の存在なのですね。
後は、黄色や赤の部分を境目に、進化前と進化後で上手く分かれているような感じもしますね。
あと、シザリガー、キングラー、サメハダーが近かったり、御三家同士が割と近くに集まっているのが良い感じですね。

ちなみに、相関行列(?)も出してみましたが、相変わらずよく分からない画像でした。

```Python
som.view_similarity_matrix(figsize=(12, 12))
```

![water_matrix.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2475646/ff666af4-6055-4656-c96a-ec71f99d6e1e.png)

ちなみに、ベビーポケモンについても同じようにマッピングしてみました。
![baby1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2475646/cfa8b8fd-1ca8-241d-784d-beefb706a550.png)

...よく分からないですね。おそらく、スボミーやウソハチと別のポケモンとの間に大きな断絶があるのは、この二匹は捕まえやすさが高い(255)だからだと思います。

初代の151匹についてもやってしまいました。やはり異端はカビゴンとラッキー！！
ピカチュウ、ビリリダマ、コイルって意外と似てるのですね。あとイーブイと御三家の進化1段階目、ポリゴンと御三家の進化2段階目って同列に設定されていたのですね。ミュウツ―に一番近い存在がリザードンというのもアツい...！！

![151.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2475646/40b26593-ba3e-a2c6-7e8d-5909f2f363d7.png)



# 感想

対象を絞った方が、割と分かりやすいマッピングになりますね。

# 参考記事

### SOMの概要、ライブラリについて

https://www.haya-programming.com/entry/2018/04/07/161249

http://gaya.jp/spiking_neuron/som.htm

http://www.brain.kyutech.ac.jp/~furukawa/data/SOMtext.pdf

https://qiita.com/ae14watanabe/items/7c70924798c8125c05eb

https://qiita.com/tohru-iwasaki/items/e51864269767ccc07254

### コード作成に関して

https://somoclu.readthedocs.io/en/stable/reference.html

https://somoclu.readthedocs.io/en/stable/example.html

https://qiita.com/kimisyo/items/97d3e7b8938984ac5bd4