毎回やる儀式

前回の課題

  • 次の図を描くコードを提出してください。

ヒント;baseballのデータセットを使います。

# head=Tは「1行目が変数名ですよ」という意味
baseball <- read.csv("ball2017.csv",fileEncoding = "UTF-8",head=T)
g <- ggplot(baseball,aes(x=PA,y=AB,color=team))+geom_point()
g <- g + facet_wrap(~league)
g

ヒント;owarai1.csvのデータセットを使います。

dat2 <- read.csv("owarai1.csv")
g <- ggplot(dat2,aes(x=アキナ,y=銀シャリ,color=ID))
g <- g + geom_point(size=5)
g

ヒント;owarai2のデータセットを使います。

dat <- read.csv("owarai2.csv")
g <- ggplot(dat,aes(x=combi,y=rate,fill=combi))
g <- g + stat_summary(fun.y=mean,geom="bar",position="dodge")
g <- g + facet_wrap(~ID)
g

別解(原理的にはこちらの方が正しい)

dat <- read.csv("owarai2.csv")
g <- ggplot(dat,aes(x=combi,y=rate,fill=combi)) + geom_bar(stat="identity")
g <- g + facet_wrap(~ID)
g

本日の話題はClustering

今日はクラスタリングです。クラスタリングとは 似ているもの同士をまとめる という操作です。例えば野球データでは,78人分のデータがあります。78人にはそれぞれの人生があるでしょうが,一人一人見ていくわけにもいかない場合,似ているいくつかのグループ(クラスター)にわけて考えた方が効率的です。

ということで,分類法は色々あるのですが,今日は一番簡単な「階層的クラスタリング」という話をしたいと思います。

階層的クラスタリング

階層的クラスタリングとは,「似ている」ケースをまとめていって,まとまったものをさらにまとめて,さらにそれをまとめて・・・と繰り返していく方法です。上に上に,ヒエラルキー(階層)を登るように積み上げていくので,階層的クラスタリングといいます。

ちなみに,非階層的クラスタリングとは,最初からいくつにまとめるかを決めてまとめ上げていく方法です。

似ている,とは。

データで考えて見ましょう。まずはわかりやすく,身長と体重という部分的なデータだけで考えて見ます。

# サブセットphysicalを作ります
physical <- subset(baseball,select=c("height","weight"))
# 一人目
physical[1,]
##   height weight
## 1    187    100
# 二人目
physical[2,]
##   height weight
## 2    178    100

この二人はどれぐらい似ているでしょうか?似ている=数字が近い,と言う意味で考えると,引き算をすればいいでしょう。

physical[1,]-physical[2,]
##   height weight
## 1      9      0

これを足し合わせて二人の距離とします。引き算のまま,ただ足すのではなく,三平方の定理を使って, \[ d_{12} = \sqrt{(x_1-x_2)^2+(y_1-y_2)^2} \] とすることで符号に関わらず二人の距離を測ることができます。

sqrt((physical[1,1]-physical[2,1])^2+(physical[1,2]-physical[2,2])^2)
## [1] 9

これが二人の距離です。 これを全員の組み合わせ分をやると大変!ですが,Rは関数一気にやってくれます。

# 1人目から5人目まで,全ての組み合わせの距離
dist(physical[1:5,],method="euclidean")
##           1         2         3         4
## 2  9.000000                              
## 3 23.769729 28.425341                    
## 4  5.099020  4.123106 26.925824          
## 5  4.472136 13.152946 24.515301  9.055385

全員分を計算すると(143*143-143)/2の数字がでます。全部印字すると大変なので,オブジェクトの中に入れておきます。

dist.physics <- dist(physical,method="euclidean")

クラスタリングの方法

この距離データを使って似ている人は同じグループとする,というのを反復して行きます。関数はhclustです。

クラスターを積み重ねていくときはいくつかの方法があるのですが,「結構綺麗に分かれてわかりやすい」ことで有名なのがWard法です。この方法で分類した例を示します。

result <- hclust(dist.physics,method="ward.D2")
plot(result)

こうして枝葉がどんどん積み上がりました。これの頃合いを見て,枝を切ります。例えば2グループに分けたいとしましょう。関数はcutree です。

cutree(result,2)
##  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 
##  1  1  1  1  1  1  1  1  1  2  1  1  1  1  1  1  1  1  2  2  2  2  2  2  2 
## 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 
##  2  2  2  2  2  2  2  2  2  1  2  2  2  2  1  2  2  2  2  2  2  2  2  2  2 
## 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 
##  1  2  2  2  2  2  1  2  1  2  2  2  2  2  2  2  2  1  2  1  2  2  2  1  2 
## 76 77 78 
##  2  2  2

こうすることで,143人が2つのグループに分かれました! この分類法をデータに追加しておくと便利です。

baseball$class <- cutree(result,2)
baseball$class <- factor(baseball$class,labels=c("CL1","CL2"))

どういうグループなんだろうね?

今回は,なんだかわからないけど似ているもの同士分類したわけですが,どう言う分かれ方をしたか気になりますよね。 ということで,データは図にしろという原理に戻って見たいと思います。

library(ggplot2)
g <- ggplot(baseball,aes(x=height,y=weight,color=class))
g <- g + geom_point()
plot(g)

そうだね!体のゴツさだね!

でもこれでは面白くないです。身長と体重を元に分類したら,身長と体重を元に分類できた,という話だからです。クラスターの説明は,クラスターを作った変数以外の変数でした方が面白いでしょう。たとえば,収入 とかね。

g <- ggplot(baseball,aes(x=class,y=pay,color=class))
g <- g + geom_boxplot()
plot(g)

体が大きい人の方が平均年収が高いようだ,ということがデータから示されました。

このように,クラスタリングは「どのような分類になったか」というのを後で考えないといけません。その時に,探索的データプロットの力を借りるといいでしょう。

縦でも横でも

M1グランプリ評定データでも同じようにやってみましょう。まずは距離行列を作ります。

# データを読み込みます。owarai1.csvを使ってください。
# 一列目は評定者の名前が入っているので除外します
dat <- read.csv("owarai1.csv")
rownames(dat) <- dat$ID
dat.dist <- dist(dat[,-1],method="euclidian")
dat.dist
##            OKD      KGW     KBYM       SK     TKHS     HMSK       MR
## KGW   28.33725                                                      
## KBYM  73.10267 87.77813                                             
## SK    41.80909 64.21059 42.61455                                    
## TKHS  19.41649 21.67948 73.19153 49.10193                           
## HMSK  14.45683 35.60899 63.34824 36.04164 21.07131                  
## MR    27.51363 45.67275 59.59027 35.65109 34.08812 26.38181         
## YMUC  32.38827 49.77951 57.34980 29.03446 37.62978 30.85450 36.41428
## YOSHI 22.67157 46.52956 56.56854 22.93469 32.35738 18.24829 20.76054
## KGA   19.10497 29.96665 68.11020 42.76681 19.59592 18.76166 35.07136
## YNGHR 19.72308 16.24808 73.84443 51.64301 12.56981 23.19483 35.94440
## KSG   29.76575 43.20880 55.42563 35.21363 25.35744 19.26136 30.18278
##           YMUC    YOSHI      KGA    YNGHR
## KGW                                      
## KBYM                                     
## SK                                       
## TKHS                                     
## HMSK                                     
## MR                                       
## YMUC                                     
## YOSHI 25.27845                           
## KGA   33.82307 28.44293                  
## YNGHR 38.93584 34.53983 18.22087         
## KSG   36.18011 25.53429 29.84962 31.95309

これは評定者同士の距離(類似度)です。これを使って階層的クラスター分析をすることもできますが,できれば芸人さんのほうを分類したい・・・というときは,データの行と列を入れ替えた距離行列を作れば良いのです。

# t()はtranspose(転置)の関数で,行と列をひっくり返します
dat.dist <- dist(t(dat[,-1]),method="euclidian")
dat.dist
##                      アキナ カミナリ 相席スタート スリムクラブ ハライチ
## カミナリ           43.41659                                            
## 相席スタート       16.88194 33.52611                                   
## スリムクラブ       32.72614 35.52464     31.49603                      
## ハライチ           28.49561 46.11941     27.65863     37.13489         
## スーパーマラドーナ 34.87119 42.79019     28.47806     39.20459 23.79075
## さらば青春の光     30.78961 31.38471     19.87461     39.86226 30.62679
## 和牛               47.30750 37.93415     37.80212     53.15073 44.49719
## 銀シャリ           28.80972 36.56501     24.14539     38.63936 22.27106
##                    スーパーマラドーナ さらば青春の光     和牛
## カミナリ                                                     
## 相席スタート                                                 
## スリムクラブ                                                 
## ハライチ                                                     
## スーパーマラドーナ                                           
## さらば青春の光               27.31300                        
## 和牛                         33.10589       28.31960         
## 銀シャリ                     20.14944       20.24846 30.69202

これで分類してみましょう。

result <- hclust(dat.dist,method="ward.D2")
plot(result)

  • カミナリとスリムクラブが似ていたのは「方言キャラ」かなあ?
  • さらば青春の光,アキナ,相席スタートはコント的なグループですね。
  • ハライチ,スーパーマラドーナ,銀シャリは漫才的なグループということかしら?

というようなグルーピングに基づく考察をすることが大切です。もちろん外部変数との比較も有効ですよ!

最後に,距離に関するうんちくを見て見ましょう。

本日の課題