【Rによるデータサイエンス】クラスター分析

【定義】
クラスター分析とは。。。
ざっくり言うと次のようになる。

クラスター分析とは、データのパターンが似ている個体を同じグループにまとめる分析方法である。

簡単そう!
でも、データのパターンの定量的定義はどうするの?とか、パターンの違いはどのように定義するの?とか、1つ1つ考えれば分からないことが沢山ある。。。

さて、はじめる前に、幾つか言葉の整理などを行う。

クラスター分析の位置づけ

目的変数が無い 目的変数が有る
主成分分析、因子分析、対応分析、多次元尺度法、クラスター分析 ・・・

クラスター分析は、主成分分析や因子分析と同様に外的規準が無い場合の多変量解析の1種である。
なお、外的規準が無いデータを「教師なしデータ」と呼び、外的規準が有るデータを「教師ありデータ」「訓練データ」と呼ぶ。

クラスター分析の種類
階層的クラスター分析と非階層的クラスター分析の2つがある。

階層的クラスター分析 非階層的クラスター分析
1つの結合の段階で随時クラスターを結合する分析方法 1回で全ての個体をいくつかのクラスターにワケ、その後ある意味でより良い分類結果になるように調整を行う分析方法
データ数が増えると計算量も膨大になる 1回で分類するので結合の途中過程は表示されないが、階層的クラスター分析と比較して計算量は少なくなる。

ある程度言葉の整理をした段階で、「似たもの同士をまとめる」ことについて考える。
「似たもの同士」、「まとめる」の2つを定量的にシステマティックにどのように考えれば良いのだろうか。

1.「似たもの同士」について
似たもの同士を考える前に、似ているとはどういうことかを定義しなければならない。
階層的、非階層的を問わず、クラスター分析では全てのデータから全ての個体間の組み合わせについて距離を定義する。そして、クラスター間、個体間の距離を用いてクラスターに分類する。つまり、「似たもの同士」というのは「距離が似たもの同士」と考えればいいのだろう。
次に、クラスター間の距離を定義する具体的な方法を整理する。

クラスター間距離の定義方法 概要 備考
最近隣法(最短距離法) それぞれのクラスター内の最も近い個体間の距離としてクラスター間の距離を定義する方法 得られるクラスターは一方の方向に長い「チェーン」になりやすくなる。
最遠隣法(最長距離法) 異なるクラスターに属する任意の個体間の最大距離としてクラスター間の距離を定義する方法。 個体がはっきりとした「集団」を形成している場合には、よく機能する。「チェーン」になることがわかっている場合は不適切。
群平均法(UPGMA) 異なるクラスターに属する全ての個体の組み合わせを考え、その個体間の距離の平均としてクラスター間の距離を定義する方法 個体がはっきりとした「集団」を形成している場合には、よく機能する。「チェーン」になることがわかっている場合でも有効。
重み付き群平均法(加重平均法、WPGMA) クラスターの大きさを重みとして使用する点を除けば、群平均法と同じ。 クラスターサイズが非常にアンバランスであると考えられる場合に使用する。
重心法(UPGMC) クラスターの重心を次元によって定義される多次元空間の平均的点と定義し、重心間の距離としてクラスター間の距離を定義する方法。 クラスター同士が結合する際の距離が前の段階よりも小さい距離をとる「距離の逆転」と呼ばれる現象が発生することがある。
重み付き重心法(メディアン法、WPGMC) クラスターの大きさの違いを考慮する点を除けば、重心法と同じ。 クラスターに含まれている個数がかなり違う場合、その疑いがある場合には、この方法が適切である。
ウォード法 各ステップで形成される任意の2つのクラスターにおけるグループ内平方和を最小にするようにクラスター間の距離を定義する方法。 他の方法とはだいぶ異なる。

2.「まとめる」について
「似たもの同士」の定義ができたら、まとめる。これは、使用する距離の定義にもとづいて、クラスターを分類することと理解している。
その手段・表現方法として樹形図(デンドログラム)を使用する*1

樹形図の特徴を次に説明する。

・左のほうで結合しているほど近い個体であることを意味する
・各個体(各クラスター)の結合を示す際の棒の高さは、その結合した際の距離をあらわす

ところで、分類方法(似たもの同士を分類する方法)って何個もありすぎる・・・。どの方法が適切なのかを評価しないといけないな。
そこで、コーフェン相関係数という概念が存在する。
コーフェン相関係数とは、解析前の距離行列とコーフェン行列の相関を求めたもの。
コーフェン行列とは、個体間の距離を要素に持つ行列である。

◎階層的クラスター分析のケーススタディ
まず最初に、階層的クラスター分析の分析プロセスは次のようになる。

1.データから距離を求める
2.クラスター分析の方法(最近隣法、最遠隣法など)を選択する
3.選択した方法のコーフェン行列を求める
4.コーフェン行列にもとづいて樹形図を作成する
5.結果の検討を行う

今回は次のデータを使用する。生徒ごとのテストの成績データである。

> seiseki
         math science japanese english society
tanaka     89      90       67      46      50
sato       57      70       80      85      90
suzuki     80      90       35      40      50
honda      40      60       50      45      55
kawabata   78      85       45      55      60
yoshino    55      65       80      75      85
saito      90      85       88      92      95

この行列の氏名ごとの成績データ(行ベクトル)同士の距離を次のように求める。

> seiseki.d<-dist(seiseki)
> seiseki.d
           tanaka     sato   suzuki    honda kawabata  yoshino
sato     68.65858                                             
suzuki   33.77869 81.11104                                    
honda    60.13319 64.14047 52.67827                           
kawabata 28.47806 60.75360 21.30728 47.10626                  
yoshino  63.37192 12.40967 75.66373 54.31390 56.38262         
saito    67.88225 38.10512 87.53856 91.53142 67.72739 45.58509

階層的クラスター分析のための関数hclustを実行する。

> seiseki.d<-dist(seiseki)
> (sei.hc<-hclust(seiseki.d))

Call:
hclust(d = seiseki.d)

Cluster method   : complete 
Distance         : euclidean 
Number of objects: 7 

分析手法はCluster methodに記載され、この場合再遠距離法を使用したことが分かる。また、距離はeuclidean定義を使用している。

> summary(sei.hc)
            Length Class  Mode     
merge       12     -none- numeric  
height       6     -none- numeric  
order        7     -none- numeric  
labels       7     -none- character
method       1     -none- character
call         2     -none- call     
dist.method  1     -none- character
> sei.hc$merge #
     [,1] [,2]
[1,]   -2   -6
[2,]   -3   -5
[3,]   -1    2
[4,]   -7    1
[5,]   -4    3
[6,]    4    5
> sei.hc$height #樹形図の枝の長さ
[1] 12.40967 21.30728 33.77869 45.58509 60.13319 91.53142
> sei.hc$order #樹形図の左から右方向の個体番号
[1] 7 2 6 4 1 3 5
> sei.hc$labels
[1] "tanaka"   "sato"     "suzuki"   "honda"    "kawabata" "yoshino" 
[7] "saito"   
> sei.hc$method
[1] "complete"
> sei.hc$call
hclust(d = seiseki.d)
> sei.hc$dist.method
[1] "euclidean"
> 

可視化する。hang=-1として葉の高さを揃えている。

・最近隣法(最短距離法)

> plot(hclust(dist(seiseki),"single"),hang=-1)

・最遠隣法(最長距離法)

> plot(hclust(dist(seiseki),"complete"),hang=-1)

・群平均法(UPGMA)

> plot(hclust(dist(seiseki),"average"),hang=-1)

・重み付き群平均法(加重平均法、WPGMA)


・重心法(UPGMC)

> plot(hclust(dist(seiseki),"centroid"),hang=-1)

・重み付き重心法(メディアン法、WPGMC)

> plot(hclust(dist(seiseki),"median"),hang=-1)

・ウォード法

> plot(hclust(dist(seiseki),"ward"),hang=-1)
The "ward" method has been renamed to "ward.D"; note new "ward.D2"
> plot(hclust(dist(seiseki),"ward.D"),hang=-1)

最後に、グラフを比較したいために、各グラフを1枚に揃える。

> par(mfrow=c(2,4)) 
> plot(hclust(dist(seiseki),"single"),hang=-1)
> plot(hclust(dist(seiseki),"complete"),hang=-1)
> plot(hclust(dist(seiseki),"average"),hang=-1)
> plot(hclust(dist(seiseki),"centroid"),hang=-1)
> plot(hclust(dist(seiseki),"median"),hang=-1)
> plot(hclust(dist(seiseki),"word"),hang=-1)

最後に、簡単に分析結果の考察方法をメモしておく。

◎樹形図のクラスタ分類
関数cutreeを使用して、指定した個数分のクラスタに分類することができる。
例えば、最近隣法(single)を使用して得られた樹形図の結果を2つのクラスタに分類したい場合は、次のようにする。

> sei.single<-hclust(dist(seiseki),"single")
> cutree(sei.single,k=2)
  tanaka     sato   suzuki    honda kawabata  yoshino    saito 
       1        2        1        1        1        2        2 

k=2として分類するクラスタの個数を指定する。
当然だが、個体の数を指定すると、個体の数とクラスタの数は等しくなる。

> cutree(sei.single,k=7)
  tanaka     sato   suzuki    honda kawabata  yoshino    saito 
       1        2        3        4        5        6        7 

◎コーフェン相関係数の計算
距離行列とコーフェン行列の相関係数を計算する。

距離としてユークリッド距離を、分類手法として最近隣法を使用した場合のコーフェン相関係数は次のように計算される。

> cor(seiseki.d,cophenetic(sei.single))
[1] 0.8915767

距離としてユークリッド距離を、分類手法として重心法を使用した場合のコーフェン相関係数は次のように計算される。

> sei.centroid<-hclust(dist(seiseki),"centroid")
> cor(seiseki.d,cophenetic(sei.centroid))
[1] 0.8276277

コーフェン相関係数の値が大きいほど、距離行列と用いた方法のコーフェン行列との歪みが少ないと判断するが、ひずみが少ないことと分類の結果がより妥当であるということは等価ではないとのこと。

この理由についてはもっと本質を勉強しないとわからないが、銀の弾丸は存在しないってことですね。

*1:樹形図は「まとめる」という行為の結果として得られるものであって、「まとめる」という行為ではないが、現段階ではアルゴリズムまでは追求しない。概要を把握する前に息切れしそうなので・・・。