「サイトウの代表は、斎藤なのか？」を科学する

# サイトウ問題
 * みなさんの近くには、「サイトウ（斎藤さん）」はいらっしゃるでしょうか？
 * そのサイトウさん、「**斎**藤」「**齋**藤」「**斉**藤」「**齊**藤」。どの字でしょうか？
 * そう！どの漢字だったか忘れてしまう。通称、「サイトウ問題」です。

# なにをやるか
 * いっそのこと、<font color=red><b>代表のサイトウを１字決めて、その字に統一できれば、、</b></font>とか考えました。
 * **漢字のカタチ**から**代表のサイトウ** を検討する過程を、ネタ的にお送り致します。
 * 次元圧縮（UMAP）とクラスタリング（主にKMeans）を用いていきます。
 * GW@外出自粛の自由研究。ネタです。ネタです。もう一度言います。ネタです。

# 漢字として認められている「斎藤」
 * ４種（新字体２つ、旧字体２つ）です。[東洋経済オンライン](https://toyokeizai.net/articles/-/65709?page=2)によると、
   * ①斎藤が、源流、
   * ②齋藤は、源流(①)の旧字体。
   * ③斉藤は、新字体(①)の書き間違い。　（驚愕の事実　その１）
   * ④齊藤は、旧字体(②)の書き間違い。　（驚愕の事実　その２
 * 下記、カッコ内の日本における人口は、**①が一番多く、斎藤が源流**　である点が感じられる。
 
||新字体|旧字体|
|:---:|:---:|:---:|
|源流|**①U+658E** (**542,000人**) <br/> ![33.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/f69f37a5-fd12-0d8f-cc45-1a90bae379c0.jpeg) <br/><font color=red><b>源流</b></font>|**②U+9F4B**（86,800人）<br/>![13.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/3aef9287-bd86-aa20-8856-521659871acb.jpeg)<br/>源流(①)の旧字体|
|実は、<br/>書き**間違い**|**③U+6589**（323,000人）<br/> ![32.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/94aaa67c-f043-f7d1-f1a2-b3a6ea5aecb8.jpeg)<br/>源流(①)の書き間違い|**④U+9F4A**（37,300人）<br/> ![2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/cd2eb041-bcfa-ddfd-0d05-346a21aadd77.jpeg)<br/>旧字体(②)の書き間違い|

# で、気持ち的には
やはり、**「斎」**（①源流）が、**全サイの字（４種）の 代表（ど真ん中）** にあってほしい。

# なので、確認してみる
* サイトウの、**代表（ど真ん中）** を確認するために、サイトウ地図を作りたい。
* 一方、利用画像は、58x58=3,364ピクセル（3,364次元）で、X-Y座標（2次元）にはマッピングできない。
* そこで、**次元圧縮**という手法を使って、**3,364次元　⇒　2次元** に圧縮をしてみたいと思います。
  * 文字の次元圧縮については、[こちらの記事](https://qiita.com/stwind/items/1c1025799b8e7a274c0f)で取り上げられているので、リンクさせていただきます。
  * 今回は、次元圧縮のアルゴリズムとして、**UMAP**を利用します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/0923566c-faa3-7cee-34a4-658ef60243f9.png)

* では、UMAPで次元圧縮しておきます。

```python
from umap import UMAP
# Umap decomposition
decomp = UMAP(n_components=2,random_state=42)
# fit_transform umap(サイトウ４文字データ)
embedding4 = decomp.fit_transform(all.T[[1,12,31,32]])
```

# 検証1) ４つのサイトウの代表を決める
* UMapを利用して、**2次元（平面）**に、**漢字画像**をマッピングし、**「代表」**を確認していきます。
* 「中心」(0.5, 0.5)ではなく、全データに対する **「重心」を「代表」** として、見ていきます。
* 「重心」は、**xマーク**で表していますが、いかがでしょう。。（重心 x の下方ですね。）

```python
from sklearn.cluster import KMeans

# clustering（クラスタ数１）
clustering = KMeans(n_clusters=1,random_state=42,)
# fit_predict cluster
cl_y = clustering.fit_predict(embedding4)

# visualize (実装は後述)
showScatter(
    embeddings    = embedding4,
    clusterlabels = cl_y,
    centers       = clustering.cluster_centers_,
    imgs          = all.T[[1,12,31,32]].reshape(-1,h,w)
)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/39364144-2e5a-9904-e41a-d2ddbe453707.png)

* **微妙ですね、、**
  * 「重心」から「各文字」へのユークリッド距離を計算するとこんな感じ。
  * この結果では、**②源流（旧字体）の齋** が代表となってしまった。。

|重心からの近さ順|文字|重心からの距離|メモ|
|:---:|:---:|:---:|:---:|
|１位|![13.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/dbfbd6cb-c1d5-8323-556f-8049e5f6fdef.jpeg)|0.6281|②源流（旧字体）|
|２位|![32.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/ee0b73d8-9c2c-fe7f-b986-07c96bf0d00b.jpeg)|0.6889|③間違い（新字体）|
|３位|![33.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/fc80391e-380b-6a20-e257-81ba96ede7a2.jpeg)|0.7339|①源流（新字体）|
|４位|![02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/9114979e-15e7-2d03-f129-48f19c8cc8f6.jpeg)|0.8743|④間違い（旧字体）|

# 検証2) 33個のサイトウの「代表」を決める
## ところで、サイトウは、何種類あるのか？
 * 漢字としては４種類だけだが、実を言うと[wikipedia](https://ja.wikipedia.org/wiki/%E6%96%8E%E8%97%A4) によれば、
  * 「斉、斎」以外の異体文字は31パターンもある。
  * 一方で、法務省が認めているサイの字は、「斎、齋、斉、齊」の４つだけ。
 * つまり、**全33パターンのうち、漢字として認められているのは４つだけ**
 * 漢字として認められているサイトウ以外に、**全33サイトウの「代表」** を見てみたい

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/cc9406c6-2843-7e29-b34d-0ce6d5ae6262.png)

* では、今度は33文字分UMAPで次元圧縮しておきます。

```python
from umap import UMAP
# Umap decomposition
decomp = UMAP(n_components=2,random_state=42)
# fit_transform umap(全33文字データ)
embeddings = decomp.fit_transform(all.T)
```

## 33個の「サイトウ」の「代表」は？
* 同じくUMAPで次元圧縮し、「重心」に近い漢字を確認していきます。

```python
from sklearn.cluster import KMeans
# clustering(クラスタ数 : 1)
clustering = KMeans(n_clusters=1, random_state=42)
# fit_predict cluster
cl_y = clustering.fit_predict(embeddings)
# visualize
showScatter(embeddings, cl_y, clustering.cluster_centers_)
```

<img width="879" alt="download.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/a40ed0c1-da45-5cb8-4654-f4e6eb7873be.png">

<div>期待していた、<b>「斎」</b> ではなく、 <img width="30" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/c1e542aa-1d6e-e9bd-de87-5b00ef32e2c8.jpeg"/>  が、代表（ど真ん中）に近い結果となってしまいました。。</div>

* 重心からの距離順（上位）は以下の通り。なかなか期待通りには行かないｗｗ

|重心からの近さ順|文字|重心からの距離|メモ|
|:---:|:---:|:---:|:---:|
|１位|![28.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/c1e542aa-1d6e-e9bd-de87-5b00ef32e2c8.jpeg)|0.494||
|２位|![30.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/c0e539a5-1149-f5d7-0c97-dcf9fe66fd8c.jpeg)|0.787||
|３位|![27.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/be7e17a4-d6b2-829e-f52e-f02e55156086.jpeg)|1.013||
|４位|![31.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/36adac28-c557-b787-243d-c8d5eb61d9c0.jpeg)|1.014||

# 検証3) 代表の「サイトウ」を４文字選ぶ
* 「ど真ん中」はうまく行かなかったのですが、漢字として認められているのは、**４種類**。
* では、この地図上の漢字を４クラスタに分離して、それぞれのクラスタの重心はどの漢字となるか？
* つまり、**全33字から、代表の4字** を選んで見たいと思います。
* クラスタリングアルゴリズムのKMeansを利用し、4クラスタに分離すると下記のとおり。

```python
from sklearn.cluster import KMeans
# clustering(クラスタ数 : 4)
clustering = KMeans(n_clusters=4, random_state=42)
# fit_predict cluster
cl_y = clustering.fit_predict(embeddings)
# visualize
showScatter(embeddings, cl_y, clustering.cluster_centers_)
```

<img width="879" alt="download.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/27b486ff-af54-309a-506b-d7e43070788d.png">

* 各クラスタの文字と重心に近い文字は下記の通り。
* なんとなく漢字の特徴（月や示）を捉えたクラスタにはなっていそう。
    * クラスタ重心の近傍点がクラスタの特徴を捉えられているか？は微妙。
    * ４クラスタだと分類しきれず、<font color="red">赤クラスタ</font>は複数のパターンを含む。
    * もう少し、**細かく分類する必要がありそう**
* ざっくり見てみると、**倍の８クラスタ**あれば、キレイに分けられそうな予感。

|No|クラスタ|重心|他に含まれる字|
|---|:---:|:---:|:---:|
|1|<font color="red"><b>赤</b></font>|![25.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/0b7fbfae-1b41-3a1b-146a-635c9a72d70c.jpeg)|![19.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/c5852fef-d4c6-0b23-e181-4fc3d79c57e7.jpeg)![33.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/d6621499-fcef-c2c6-8fe5-539da8c2cb56.jpeg)![20.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/0746c1b3-76b6-af44-db1b-ea4b292204bc.jpeg)![21.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/f19d0289-afb6-4fa7-a2a5-d580f874189e.jpeg)　![27.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/3fbb1b71-68f8-d047-4182-7f32d0f0efcf.jpeg)![28.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/c0187789-e93b-fa04-6c7d-203f6c77a507.jpeg)　![30.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/a29c556d-5d41-0a95-3f3c-a7f1beb45fa3.jpeg)![31.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/61a3e76c-ed98-026e-70e7-209adb53eaa6.jpeg)|
|2|<font color="orange"><b>橙</b></font>|![26.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/bcb0bf99-8a58-4b05-8007-d67299dd5068.jpeg)|![13.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/898095c0-49dc-27d9-1498-a9a4d2dc22c8.jpeg)![14.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/9152faac-5115-6cd4-8591-256140062630.jpeg)![15.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/23282f90-11b1-ab48-911c-dd8fa8bb2dc2.jpeg)![16.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/d5232d8d-fd9b-4f20-48c0-2236e71eed9e.jpeg)![17.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/95cf581d-090f-cf19-3f57-7dcc1ec4d7ed.jpeg)![18.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/de61805a-b740-d26a-d3d3-b4ac17a49405.jpeg)![22.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/eaf6ca4f-5cc3-9a5e-94f0-f8804d213cde.jpeg)![23.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/5fe06da6-d2f0-d72a-30eb-8149d6e0e884.jpeg)![24.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/1e83659f-4a00-8e1a-a9a4-007bd44b3fcc.jpeg)|
|3|<font color="blue"><b>青</b></font>|![29.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/a4de5e1e-620b-77ae-bcb9-6331fe7c97d1.jpeg)|![10.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/efa11a12-81e8-22ab-0d89-a5dc2c754a05.jpeg)![32.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/22ebdbe4-1a0f-0888-1fd2-693acfeffdd0.jpeg)　![11.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/0837bbe6-36ac-5273-a093-3895c5ea72d1.jpeg)|
|4|<font color="green"><b>緑</b></font>|![08.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/d2db1c57-dbb7-ac70-b22d-6e34cb9e7b17.jpeg)|![01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/3f818c89-81ce-aa83-c210-ef80ba74654d.jpeg)![02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/ef8fe0ca-a016-3424-9b1f-6a9035b6cb6e.jpeg)![03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/308c859e-3a2e-1fe1-99fd-fb81bc3580d7.jpeg)![04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/26df8089-7412-4ead-1009-655ec27b74ef.jpeg)![05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/78e6e45e-8a78-1760-4622-20e18740c8bf.jpeg)![06.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/bb70a32c-6676-1704-c209-becc5e8b6f58.jpeg)![07.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/1fb32ae4-0b6f-f736-f825-f6ed93528705.jpeg)![08.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/83670f21-6906-dd28-d8cd-f73ec9db39df.jpeg)　![12.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/443d1737-754d-259f-3edb-b8647a5b2a88.jpeg)|

# 検証4) ８クラスタ化してみる
* 先程は、代表の漢字を４文字選ぶために４クラスタでした。
* ただ、結果を見ると、キレイに分離できていないクラスタも存在したので、クラスタ数を８にしてみます。
* 結果は下記の通り。


```python
from sklearn.cluster import KMeans
# clustering(クラスタ数 : 8)
clustering = KMeans(n_clusters=8, random_state=42)
# fit_predict cluster
cl_y = clustering.fit_predict(embeddings)
# visualize
showScatter(embeddings, cl_y, clustering.cluster_centers_)
```

<img width="879" alt="download.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/d9968b09-f0e9-1765-7879-58335667bf29.png">

* キレイに分離ができているわけではないですが、なんとなく仕分けできた感じです。


|No|クラスタ|クラスタに含まれる字|
|---|:---:|:---:|
|1|<font color="#ff5efc" ><b>桃</b></font>|![13.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/f0700fb0-782b-09c9-766e-34d4336cc61b.jpeg)![15.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/56a08fea-4caa-0b32-5115-0f79c1ecdf51.jpeg)![33.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/f8c4c91e-2929-ff95-313e-44cc1703eaae.jpeg)![18.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/87ef9d0c-e895-7798-ce1c-90293d8d69b8.jpeg)|
|2|<font color="red" ><b>赤</b></font>|![14.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/664e27e1-5e5a-c3ae-180a-911804f4c6c6.jpeg)![22.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/bda92a65-90ae-5f94-5d8d-c1713dee1a08.jpeg)![24.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/6fc058f6-ff75-451f-92dc-632e784a08dc.jpeg)![26.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/4918aa38-e580-3df4-7d09-80f1e6c8e57b.jpeg)|
|3|<font color="#6b2903" ><b>茶</b></font>|![16.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/a5196f72-1cee-c388-4d94-c06f5a0714a7.jpeg)![17.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/56eafda9-ad5f-eb49-943d-3ce2f22f7753.jpeg)![23.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/7b935e7f-01cc-21fc-7e81-804b6b68f1f9.jpeg)|
|4|<font color="gray" ><b>灰</b></font>|![30.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/ea2e886a-f490-5fe6-aa0e-06bab82f4f7a.jpeg)![31.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/920f419e-354d-1630-ae89-858d4e0a4367.jpeg)　![28.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/41d8af33-73e7-d806-fa27-2092ba047db7.jpeg)|
|5|<font color="orange" ><b>橙</b></font>|![19.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/57e6618c-0640-0ee7-1030-2da71f0eef24.jpeg)![20.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/919e4e0f-12f3-4a25-edab-e1028f2be0be.jpeg)![21.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/9ec7f207-8a9d-361f-0b93-40f7531c9ee3.jpeg)![25.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/e575d2ef-ca07-6fac-ab67-2f8c5d62fa2d.jpeg)　![27.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/86c577cc-8b82-5cb5-22fc-d16e268f729f.jpeg)|
|6|<font color="blue" ><b>青</b></font>|![10.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/ef217aca-ddc9-85f8-16e3-c392a24c777e.jpeg)![32.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/2af1c44d-731d-e8f4-ef26-b046cbfb3182.jpeg)![29.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/7fe9ebb0-d9a8-54ca-3f50-287ffe11ad0a.jpeg)|
|7|<font color="#a832a0" ><b>紫</b></font>|![11.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/e751e6d3-6fe0-02d5-506d-595dba6c4247.jpeg)![12.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/3d9a4866-c2a9-0f10-e5e1-f231863e5dcf.jpeg)![01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/e34c276f-d758-d603-8d87-87489d42030a.jpeg)|
|8|<font color="green" ><b>緑</b></font>|![02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/ef8fe0ca-a016-3424-9b1f-6a9035b6cb6e.jpeg)![03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/308c859e-3a2e-1fe1-99fd-fb81bc3580d7.jpeg)![04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/26df8089-7412-4ead-1009-655ec27b74ef.jpeg)![05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/78e6e45e-8a78-1760-4622-20e18740c8bf.jpeg)![06.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/bb70a32c-6676-1704-c209-becc5e8b6f58.jpeg)![07.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/1fb32ae4-0b6f-f736-f825-f6ed93528705.jpeg)![08.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/83670f21-6906-dd28-d8cd-f73ec9db39df.jpeg)![09.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/e3145503-0615-7157-f297-745027da8456.jpeg)|

* 惜しいのは、<font color="orange"><b>橙</b></font>の![27.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/666133d0-3d55-6c0a-de96-ef8ab943afbe.jpeg) と、<font color="gray" ><b>灰</b></font>の![28.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/0ba6a86b-3e46-d8a4-d2ac-6443ecda4d83.jpeg)で、クラスタが割れてしまっています。
* ただ、両者ともクラスタの境界線上のデータであるため、思いは伝わってきます（笑）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/47a9f9fe-1997-08ba-eb01-4eecebe016c8.png)

# 検証5) 何クラスタが妥当かを確認する
* 漢字として登録のある４字に合わせて、４クラスタ。
* そして、４クラスタの結果をみて、８クラスタに分離してみたわけですが、、
* 果たして、**何クラスタにするのが適切なのでしょうか？**
* ここでは、クラスタ数を選定する方法として、下記３手法でクラスタの状態を可視化、検討してみたいと思います。
  1. Elbow Chart
  2. Silhouette Chart
  3. dendrogram

## Elbow Chart
* elbow chartは縦軸に **各クラスタでのデータのばらつき** 、横軸に **クラスタ数** をとった図です。
* クラスタの数を多くすれば、ばらつきを抑えることが出来ますが、クラスタ数が多すぎるのも問題です。
* そこで、**そこそこのクラスタ数** でかつ **データのばらつきも抑えられる** クラスタ数をこの図で検討します。
* 作図には、[Yellowbrick](https://www.scikit-yb.org/en/latest/api/cluster/elbow.html)を利用していきます。

```python
from yellowbrick.cluster import KElbowVisualizer
vis = KElbowVisualizer(
    KMeans(random_state=42),
    k=(1,34) # クラスタ数（横軸の範囲)
)
vis.fit(embeddings)
vis.show()
```

<img width="700" alt="download.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/5370dce5-5220-d11c-0daa-6a483c971e8e.png">

* 見ている感触では、
 * クラスタ数５までは、順調に **データのばらつき（の平均）は下がり** が、以降はフラットに。
 * よって、**５クラスタに分類** が良さそう　＝　代表の漢字は **５種** が良さそうです。
* が、一応拡大版も見ておきましょう（４～１８で拡大）
 * ５に変曲点がありそうなのですが、**概ね10付近** からフラットになっています。
 * つまり、 **感覚で８クラスタに分類し、代表漢字を８個決めた** のも間違いではなさそうです。

```python
from yellowbrick.cluster import KElbowVisualizer
vis = KElbowVisualizer(
    KMeans(random_state=42),
    k=(4,19) # クラスタ数（横軸の範囲)
)
vis.fit(embeddings)
vis.show()
```

<img width="700" alt="download.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/2c4ea1f3-2365-fd6a-4111-6028eaecd634.png">

## Silhouette Chart
* Silhouette Chartは、クラスタ毎に下記を表現した図です。
  *  縦軸（グラフの厚み）　：　そのクラスタのサンプル数
  *  横軸（グラフの長さ）　：　そのクラスタのシルエット係数
  *  破線　：　シルエット係数の平均
* 見方としては、下記を満たすようなグラスタ数を見つけるのがポイントです。
  * どのクラスタも同じサンプル数　＝　厚みが一緒
  * どのグラスタもシルエット係数が平均に近い　＝　長さが破線に近い
* 作図には、同じく[Yellowbrick](https://www.scikit-yb.org/en/latest/api/cluster/elbow.html)を利用していきます。

```python
from yellowbrick.cluster import silhouette_visualizer
fig = plt.figure(figsize=(15,25))
# クラスタ数4～9までまとめて作図
for i in range(4,10):
    ax = fig.add_subplot(4,2,i-1)
    silhouette_visualizer(KMeans(i),embeddings)
```

* 見る感じでは、右上（**クラスタ数５**）のパターンがいい感じです。
<img width="904" alt="download.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/4b28a191-9c89-c69c-3448-5ba6ed2ec52b.png">

## dendrogram
* クラスタ同士の **近さ** をトーナメント表の様に表現したグラフです。
* 階層型クラスタリングで利用できる図ですので、KMeansでなく、Scipyの階層型クラスタリングを使っています。
* 見方としては、下記です。
    * 葉がデータで、同じ色の枝の範囲が同じクラスタ
    * 高さが、クラスタ間の距離

```python
from scipy.cluster.hierarchy import linkage, dendrogram
Z = linkage(
    y = embeddings,
    method = 'weighted',
    metric = "euclidean",
)

R = dendrogram(
    Z=Z,
    color_threshold=1.2, #この閾値でクラスタ数を調整
    show_contracted=False,
)
```

* **各色の枝の数がバランスよく、高さも揃っていると** いい感じです。やはり、クラスタ数は５程度でしょうか。



|クラスタ数|デンドログラム|コメント|
|:---:|:---:|:---:|
| **４** |<img width="600" alt="download.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/42aaff5d-661d-f9e1-a8f8-75b914354a1f.png">|<font color=red><b>赤</b></font>だけ、少し高い|
|**５**|<img width="893" alt="download.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/a2ef8620-116a-84fa-5f7b-ccf533c991e7.png">|高さは揃っている<br/><font color="#a832a0"><b>紫</b></font>の少数が気になるが <br/> **なかなかいい感じ**|
|**８**|<img width="893" alt="download.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/3e2a7abb-cadf-5bb0-8fb9-85f26f24cb09.png">|高さ、数も揃っているが、<br/> **細かく分割しすぎか**|

# 検証6) ５クラスタにしてみる
* クラスタ数を検討してみたので、再び、５クラスタでどんな感じになるかプロットしてみたいと思います。
* なかなか良さそうですね。やはり、５クラスタでしょうか。

```python
from sklearn.cluster import KMeans
# clustering(クラスタ数 : 5)
clustering = KMeans(n_clusters=5, random_state=42)
# fit_predict cluster
cl_y = clustering.fit_predict(embeddings)
# visualize
showScatter(embeddings, cl_y, clustering.cluster_centers_)
```

<img width="879" alt="download.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/d56b970f-a696-745f-dbcc-de7d8b5a0816.png">


|No|クラスタ|重心|他に含まれる字|
|---|:---:|:---:|:---:|
|1|<font color="blue"><b>青</b></font>|![15.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/23282f90-11b1-ab48-911c-dd8fa8bb2dc2.jpeg)|![13.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/898095c0-49dc-27d9-1498-a9a4d2dc22c8.jpeg)![14.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/9152faac-5115-6cd4-8591-256140062630.jpeg)![33.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/d6621499-fcef-c2c6-8fe5-539da8c2cb56.jpeg)![18.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/de61805a-b740-d26a-d3d3-b4ac17a49405.jpeg)|
|2|<font color="#a832a0" ><b>紫</b></font>|![23.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/5fe06da6-d2f0-d72a-30eb-8149d6e0e884.jpeg)|![16.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/d5232d8d-fd9b-4f20-48c0-2236e71eed9e.jpeg)![17.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/95cf581d-090f-cf19-3f57-7dcc1ec4d7ed.jpeg)![22.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/eaf6ca4f-5cc3-9a5e-94f0-f8804d213cde.jpeg)![24.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/1e83659f-4a00-8e1a-a9a4-007bd44b3fcc.jpeg)![26.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/bcb0bf99-8a58-4b05-8007-d67299dd5068.jpeg)![21.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/f19d0289-afb6-4fa7-a2a5-d580f874189e.jpeg)|
|3|<font color="green"><b>緑</b></font>|![27.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/3fbb1b71-68f8-d047-4182-7f32d0f0efcf.jpeg)|![19.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/c5852fef-d4c6-0b23-e181-4fc3d79c57e7.jpeg)![20.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/0746c1b3-76b6-af44-db1b-ea4b292204bc.jpeg)![25.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/0b7fbfae-1b41-3a1b-146a-635c9a72d70c.jpeg)　![27.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/3fbb1b71-68f8-d047-4182-7f32d0f0efcf.jpeg)![28.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/c0187789-e93b-fa04-6c7d-203f6c77a507.jpeg)　![30.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/a29c556d-5d41-0a95-3f3c-a7f1beb45fa3.jpeg)![31.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/61a3e76c-ed98-026e-70e7-209adb53eaa6.jpeg)|
|4|<font color="red"><b>赤</b></font>|![29.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/a4de5e1e-620b-77ae-bcb9-6331fe7c97d1.jpeg)|![32.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/22ebdbe4-1a0f-0888-1fd2-693acfeffdd0.jpeg)![10.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/efa11a12-81e8-22ab-0d89-a5dc2c754a05.jpeg)　![11.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/0837bbe6-36ac-5273-a093-3895c5ea72d1.jpeg)|
|5|<font color="orange"><b>橙</b></font>|![08.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/83670f21-6906-dd28-d8cd-f73ec9db39df.jpeg)|![01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/3f818c89-81ce-aa83-c210-ef80ba74654d.jpeg)![02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/ef8fe0ca-a016-3424-9b1f-6a9035b6cb6e.jpeg)![03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/308c859e-3a2e-1fe1-99fd-fb81bc3580d7.jpeg)![04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/26df8089-7412-4ead-1009-655ec27b74ef.jpeg)![05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/78e6e45e-8a78-1760-4622-20e18740c8bf.jpeg)![06.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/bb70a32c-6676-1704-c209-becc5e8b6f58.jpeg)![07.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/1fb32ae4-0b6f-f736-f825-f6ed93528705.jpeg)![09.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/e3145503-0615-7157-f297-745027da8456.jpeg)　![12.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/443d1737-754d-259f-3edb-b8647a5b2a88.jpeg)|


# まとめ
## 所感
* 流れとしては、
    * 漢字として登録されている４文字の代表選びからスタートし
    * 漢字として登録のない全３３字については、１，４，８文字を選び
    * 適切なクラスタ数を検討し、５クラスタが良さそうということで、最後に５文字選びました
* 代表漢字は下記となるわけですが、代表を決める以上に
    * 3000次元を次元圧縮したXY平面上で、**カタチの似た漢字は近傍に配置**される点も興味深いですし
    * 距離ベースのクラスタリングで、**部首毎のグループ**が作れることは興味深かった
    * クラスタ数の検討も、エルボー法、シルエット法、デンドグラムでの検討結果で５クラスタと判断し
    * ５クラスタのクラスタリング可視化の**結果もそこそこしっくりくる点**も面白かったです。

## 検証一覧
|No|選び方|代表のサイトウ たち|
|:---:|:---:|:---:|
|1|認められた４漢字から<br/>**１字**選ぶなら代表は|![13.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/b50231b6-63d7-9277-5c54-c408d181c3e3.jpeg)|
|2|全33漢字から<br/>**１字** 選ぶなら|![28.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/2bbb152e-b462-affc-e91b-4583bee84c66.jpeg)|
|3|全33漢字から<br/>**４字**選ぶなら|![25.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/544545a0-1dff-7864-2d3b-2a266a577291.jpeg) ![26.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/227f5e4d-ead4-28bc-b28f-eeb59d87cc9c.jpeg) ![29.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/9ec27c29-2863-c3d9-926a-6dbd7c04c819.jpeg) ![08.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/14ae42c3-64bd-3bad-eb45-1cb1d49b83b5.jpeg)|
|4|全33漢字から<br/>**８字**選ぶなら|![21.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/f7733307-771e-af4d-18ce-f65547c6578e.jpeg) ![26.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/f9f101ec-9fd7-c98d-0915-d9c2e6517f2e.jpeg) ![29.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/b5fe8a94-0b9c-00e3-f714-55bbaea9a0e5.jpeg) ![31.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/33cc5a6a-d2ca-79db-b393-d5016b75c2e9.jpeg) ![07.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/ada2f2ca-9c36-fa32-5543-02f9136047be.jpeg) ![12.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/4f97449d-753e-ecc2-1a3c-9a6c6ac1834c.jpeg) ![15.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/81b2a0c6-d523-49ad-47c9-1fac969711fd.jpeg) ![19.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/c0f41e5b-c005-2a56-f0f0-ba85439ebe79.jpeg)|
|5|全33漢字を<br/>**何クラスタ**に分けるべきかは|**５クラスタ程度** が良さそう|
|6|全33漢字から<br/>**５字**選ぶなら|![08.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/042b5a36-d736-3fbb-5313-d821133593bc.jpeg) ![15.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/01fc51dc-999c-c248-a345-b20bef7fc8df.jpeg) ![23.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/0d65c276-e2f6-365e-e988-062ef959903b.jpeg)  ![27.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/dae9c447-ef81-26da-f70f-8811c50d10c2.jpeg) ![29.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/b7728b8f-36dc-51ab-5414-63ca3c65bce3.jpeg)|

# 最後に
* こんなくだらないネタにお付き合い頂きありがとうございました。
* よろしくければ、いいね、シェアしていただければ嬉しいです。

# 参考情報
* UMAPについて
    * https://umap-learn.readthedocs.io/en/latest/index.html
* UMAPでのClusteringについての議論（があるようです）
    * https://umap-learn.readthedocs.io/en/latest/index.html
* KMeansについて
    * https://scikit-learn.org/stable/modules/generated/sklearn.cluster.KMeans.html
* クラスタ数の検討について(YellowBrick)
    * https://www.scikit-yb.org/en/latest/api/cluster/elbow.html
    * https://www.scikit-yb.org/en/latest/api/cluster/silhouette.html
* デンドログラムでの作図
    * https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.cluster.hierarchy.dendrogram.html

# 可視化関数
* [こちらの記事](https://qiita.com/stwind/items/1c1025799b8e7a274c0f)を参考にさせていただきました。ありがとうございます。リンクさせていただきます。

```python
%matplotlib inline
%config InlineBackend.figure_format = 'retina'

import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib.lines as mlines
from matplotlib import offsetbox
from sklearn.preprocessing import MinMaxScaler
from PIL import Image
import matplotlib.patches as patches

rc = {
  'font.family': ['sans-serif'],
  'font.sans-serif': ['Open Sans', 'Arial Unicode MS'],
  'font.size': 12,
  'figure.figsize': (8, 6),
  'grid.linewidth': 0.5,
  'legend.fontsize': 10,
  'legend.frameon': True,
  'legend.framealpha': 0.6,
  'legend.handletextpad': 0.2,
  'lines.linewidth': 1,
  'axes.facecolor': '#fafafa',
  'axes.labelsize': 10,
  'axes.titlesize': 14,
  'axes.linewidth': 0.5,
  'xtick.labelsize': 10,
  'xtick.minor.visible': True,
  'ytick.labelsize': 10,
  'figure.titlesize': 14
}
sns.set('notebook', 'whitegrid', rc=rc)

def colorize(d, color, alpha=1.0):
  rgb = np.dstack((d,d,d)) * color
  return np.dstack((rgb, d * alpha)).astype(np.uint8)

colors = sns.color_palette('tab10')

def showScatter(
    embeddings,
    clusterlabels,
    centers = [],
    imgs = all.T.reshape(-1,h,w),
):
    fig, ax = plt.subplots(figsize=(15,15))
    
    #散布図描画前にスケーリング
    scaler = MinMaxScaler()
    embeddings = scaler.fit_transform(embeddings)
    
    source = zip(embeddings, imgs ,clusterlabels)
    
    #漢字を散布図に描画
    cnt = 0
    for pos, d , i in source:
        cnt = cnt + 1
        img = colorize(d, colors[i], 0.5)
        ab = offsetbox.AnnotationBbox(offsetbox.OffsetImage(img),0.03 + pos * 0.94,frameon=False)
        ax.add_artist(ab)
          
    #重心からの同心円を描画
    if len(centers) != 0:
        for c in scaler.transform(centers):
            for r in np.arange(3,0,-1)*0.05:
                circle = patches.Circle(
                    xy=(c[0], c[1]),
                    radius=r,
                    fc='#FFFFFF', 
                    ec='black'
                )
                circle.set_alpha(0.3)
                ax.add_patch(circle)

            ax.scatter(c[0],c[1],s=300,marker="X")
  

    # 軸の描画範囲
    limit = [-0.1,1.1]
    plt.xlim(limit)
    plt.ylim(limit)
    plt.show()
```