次元の海で溺れる

Rとデータ解析と統計手法たちとわたし

ggplot2実践編:都道府県別身長体重を使ってクラスタリング&結果の可視化

明日からお仕事~
来週はいよいよSapporo.R~

ggplot2とだんだん仲良くなってきた気がしなくもないので、
今週もしつこくggplot2をやります。

慣れたら超楽しいね、ggplot2!!!!
まだまだポンコツだけど!!!

今回のお題

【仮  説 】身長体重って、なんか地域によって特性ありそうじゃない?

【使用データ】総務省統計局/学校保健調査平成26年「都道府県別/身長・体重・座高」17歳男女

【分析の流れ】
 1.まずふつーーーに図示してみる。データ全体の把握。
 2.k-平均法でクラスタリングしてみる
 3.結果をうまいことggplot2に反映出来たらいいな

【動機】完全に思いつきです。

困ったときの教科書

いつもの2冊です。

パターン認識 (Rで学ぶデータサイエンス 5)

パターン認識 (Rで学ぶデータサイエンス 5)

Rグラフィックスクックブック ―ggplot2によるグラフ作成のレシピ集

Rグラフィックスクックブック ―ggplot2によるグラフ作成のレシピ集

でも今回全然開かなかった、成長。

早速やります

#統計局e-statより、学校保健調査平成26年度の調査表をお借り。
#17歳男女の身長・体重平均値です

> data
         NAME m_height m_weight w_height w_weight
1  北 海 道    170.9     63.3    157.9     53.4
2  青   森    171.1     63.8    158.5     54.6
3  岩   手    170.3     64.4    157.6     53.4
4  宮   城    170.9     64.9    158.2     53.7
5  秋   田    171.4     65.7    158.3     53.5
6  山   形    170.8     65.0    157.7     53.5
7  福   島    170.3     62.5    157.9     54.1
8  茨   城    170.2     63.0    157.8     53.0
9  栃   木    170.4     63.0    157.3     54.5
10 群   馬    170.8     63.0    158.0     53.5
11 埼   玉    171.0     62.0    158.2     52.9
12 千   葉    170.9     62.6    157.8     53.5
13 東   京    170.9     62.2    158.6     52.3
14 神 奈 川    171.1     62.4    158.0     52.3
15 新   潟    170.8     62.6    158.1     53.4
16 富   山    171.4     63.5    158.1     53.1
17 石   川    171.7     63.5    158.4     52.7
18 福   井    171.3     63.2    158.3     53.2
19 山   梨    170.6     63.3    158.0     52.6
20 長   野    170.5     62.5    157.5     52.5
21 岐   阜    171.2     62.4    157.7     52.2
22 静   岡    170.4     61.7    158.0     52.5
23 愛   知    170.7     62.3    157.9     52.7
24 三   重    170.7     63.1    157.6     52.4
25 滋   賀    171.1     62.9    158.1     52.6
26 京   都    171.0     62.3    157.9     52.7
27 大   阪    171.2     62.5    158.5     53.2
28 兵   庫    170.4     62.5    158.0     53.0
29 奈   良    170.9     62.5    157.7     51.9
30 和 歌 山    170.7     62.9    157.9     53.0
31 鳥   取    171.1     62.1    158.4     53.1
32 島   根    169.8     61.9    157.5     53.2
33 岡   山    170.3     62.5    157.1     52.7
34 広   島    169.8     62.6    157.6     52.7
35 山   口    170.9     62.2    157.1     52.4
36 徳   島    170.0     63.4    156.6     53.2
37 香   川    170.1     62.2    157.1     52.1
38 愛   媛    170.2     62.7    157.0     53.0
39 高   知    169.8     62.9    157.4     52.7
40 福   岡    169.3     61.3    157.7     52.8
41 佐   賀    170.1     62.5    157.5     52.5
42 長   崎    170.7     63.5    157.1     53.0
43 熊   本    170.7     63.3    157.5     53.3
44 大   分    170.0     62.7    157.2     53.4
45 宮   崎    170.0     63.2    157.1     52.7
46 鹿 児 島    170.0     62.2    157.5     53.3
47 沖   縄    168.8     61.1    155.8     51.3


#m_height,m_weight:男性平均身長・体重
#w_height,w_weight:女性平均身長・体重

#データはrawのままいじってません

library(ggplot2)

#いったん描いてみよう
ggplot(data,aes(x=m_weight,y=m_height))+
  geom_point()

#男性の身長をy,体重をxと置いてるだけ

f:id:WAFkw:20150607214420p:plain

うん、、
ラベル付けたい、、、

どうやらgeom_text()を使って自動的にラベル付けが出来そう。

> #プロットの色とかサイズとかを整えてオブジェクト化
> sp=ggplot(data,aes(x=m_weight,y=m_height))+
+   geom_point(colour="orange",size=4)

> sp+geom_text(aes(label=NAME),size=3,vjust=-1)

f:id:WAFkw:20150607214902p:plain

ちゃんと都道府県の名前が入りました。
ちなみに、このvjustという引数で若干ラベルの位置を調整出来ます。

色々試した結果、正の方向に動かすとラベルが下方向に
負の方向に増やすとラベルが上方向に動いてくれます。

今回はplotとラベルがかぶってたのでvjust=-1でちょい上にズラしてみました。


ここでplotを見てみると、

東北→体重が重め、ガタイよさげ
北陸・関東→身長高め、体重軽め~標準
九州・沖縄→小柄め

って感じに、なんとなく3グループに分けられそう。

ほんとかどうか確かめてみたい・・・

#なんか2、3個のグループに分けられそう、、、

#K-means法でクラスタリングしてみる

library(kernlab)
x=as.matrix(data[,2:3])
#(なんかNAMEの文字列処理に自信がなかったので切り出し。意味はないです)

#クラスタ数3,初期値10で探索開始。
cl=kmeans(x,3,nstart=10)


#評価値を算出。なかなか小さい値なのでいい感じ?
> sum(cl$withinss)
[1] 19.00378

#クラスタリング結果
> print(cl)
K-means clustering with 3 clusters of sizes 25, 18, 4

Cluster means:
  m_height m_weight
1  170.952 62.81600
2  170.000 62.41111
3  170.850 65.00000

Clustering vector:
 [1] 1 1 3 3 3 3 2 2 1 1 1 1 1 1 1 1 1 1 1 2 1 2 1 1 1 1 1 2 1 1 1 2 2 2 1 2 2 2 2 2 2 1 1 2 2 2 2

Within cluster sum of squares by cluster:
[1] 8.396000 9.137778 1.470000
 (between_SS / total_SS =  62.6 %)

Available components:

[1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss" "betweenss"   
[7] "size"         "iter"         "ifault"      


> #ggplot2でのクラスタリング結果の反映を考える

> #クラスタを切り出してみた
> cl1=data.frame(cl$cluster)
> cl1
   cl.cluster
1           1
2           1
3           3
4           3
5           3
6           3
7           2
8           2
9           1
10          1
11          1
12          1
13          1
14          1
15          1
16          1
17          1
18          1
19          1
20          2
21          1
22          2
23          1
24          1
25          1
26          1
27          1
28          2
29          1
30          1
31          1
32          2
33          2
34          2
35          1
36          2
37          2
38          2
39          2
40          2
41          2
42          1
43          1
44          2
45          2
46          2
47          2

#うまいことplotに反映させたいよねー

#元データとくっつけてみた
cl2=cbind(data$NAME,data$m_height,data$m_weight,cl1)#ダサい

#みてみる
>cl2
    data$NAME data$m_height data$m_weight cl.cluster
1  北 海 道         170.9          63.3          1
2  青   森         171.1          63.8          1
3  岩   手         170.3          64.4          3
4  宮   城         170.9          64.9          3
5  秋   田         171.4          65.7          3
6  山   形         170.8          65.0          3
7  福   島         170.3          62.5          2
8  茨   城         170.2          63.0          2
9  栃   木         170.4          63.0          1
10 群   馬         170.8          63.0          1
11 埼   玉         171.0          62.0          1
12 千   葉         170.9          62.6          1
13 東   京         170.9          62.2          1
14 神 奈 川         171.1          62.4          1
15 新   潟         170.8          62.6          1
16 富   山         171.4          63.5          1
17 石   川         171.7          63.5          1
18 福   井         171.3          63.2          1
19 山   梨         170.6          63.3          1
20 長   野         170.5          62.5          2
21 岐   阜         171.2          62.4          1
22 静   岡         170.4          61.7          2
23 愛   知         170.7          62.3          1
24 三   重         170.7          63.1          1
25 滋   賀         171.1          62.9          1
26 京   都         171.0          62.3          1
27 大   阪         171.2          62.5          1
28 兵   庫         170.4          62.5          2
29 奈   良         170.9          62.5          1
30 和 歌 山         170.7          62.9          1
31 鳥   取         171.1          62.1          1
32 島   根         169.8          61.9          2
33 岡   山         170.3          62.5          2
34 広   島         169.8          62.6          2
35 山   口         170.9          62.2          1
36 徳   島         170.0          63.4          2
37 香   川         170.1          62.2          2
38 愛   媛         170.2          62.7          2
39 高   知         169.8          62.9          2
40 福   岡         169.3          61.3          2
41 佐   賀         170.1          62.5          2
42 長   崎         170.7          63.5          1
43 熊   本         170.7          63.3          1
44 大   分         170.0          62.7          2
45 宮   崎         170.0          63.2          2
46 鹿 児 島         170.0          62.2          2
47 沖   縄         168.8          61.1          2


#クラスタリング結果で先ほどのplotを色分けしてみる

#やり方はほぼさっきと一緒。カラーの引数をクラスタにしてみた

cl3=ggplot(cl2,aes(x=data$m_weight,y=data$m_height,colour=cl.cluster))+
  geom_point(size=4)
cl3+geom_text(aes(label=data$NAME),colour="grey40",size=3,vjust=-1)


f:id:WAFkw:20150607220037p:plain


できたーーーー

ちょっと色味がわかりにくいけど、
さっきなんとなく仮説立てた通り

東北→体重が重め、ガタイよさげ
北陸・関東→身長高め、体重軽め~標準
九州・沖縄→小柄め

って感じの3群になった・・・

k-means法の理論的背景とか、その辺も書きたかったし、
そもそもクラスタ結果は色分けじゃなくてshapeで△と〇とかに分けたかったけど

次回にしよう、、、(なぜかshape失敗したし・・・)

以上です。たのしかった。