【R】階層的クラスタリングのクラスタ数決定方法

階層的クラスタリングを用いて分析をする際にクラスタ数をいくつに設定するか悩むことがあるかと思います。

今回はギャップ統計量というクラスタ数を決定するときの代表的な手法について解説していきたいと思います。

 

階層的クラスタリングの実行方法については下記で解説しています。

【R】階層的クラスタリングのやり方と結果の見方

クラスタ数の決定方法

ギャップ統計量

ギャップ統計量は対象とするデータをクラスタリングして得られたクラスタと、ランダムなデータをクラスタリングして得られたクラスタのまとまり具合の差を表す指標のことです。

 

ギャップ統計量が大きくなるクラスタ数を最適値として、採用してみます。

まず、最大10のクラスタ数に設定して、ウォード法によってクラスタリングを行ってみます。

library(cluster)
library(dplyr)
library(ggplot2)
set.seed(71)

# 最大クラスタ数を10に設定
k.max <- 10

# ward法を実行して各データのクラスタ番号を返す関数を作成
get.cluster_id <- function(x, k) {
# データ間の距離の算出
dist.x <- dist(x)
# ward法による階層的クラスタリングの実行
hc.x <- hclust(dist.x, method = "ward.D2")
# 各データのクラスタ番号の算出
ct.x <- cutree(hc.x, k = k)
list(cluster = ct.x)
}

# ギャップ統計量の算出
gap.ward.cars <- clusGap(cars, FUNcluster = get.cluster_id, K.max = k.max)
gap.ward.cars
Clustering Gap statistic ["clusGap"] from call:
clusGap(x = cars, FUNcluster = get.cluster_id, K.max = k.max)
B=100 simulated reference sets, k = 1..10; spaceH0="scaledPCA"
--> Number of clusters (method 'firstSEmax', SE.factor=1): 1
logW E.logW gap SE.sim
[1,] 5.903133 6.210237 0.30710371 0.06722676
[2,] 5.425005 5.557476 0.13247085 0.07486908
[3,] 5.030537 5.171464 0.14092703 0.06622287
[4,] 4.916939 4.891793 -0.02514606 0.05923372
[5,] 4.682881 4.693704 0.01082350 0.05985784
[6,] 4.502633 4.533998 0.03136544 0.05434815
[7,] 4.321601 4.413038 0.09143679 0.05661758
[8,] 4.184089 4.305152 0.12106367 0.05881827
[9,] 4.084424 4.208229 0.12380483 0.06129238
[10,] 3.957020 4.118171 0.16115096 0.06408056

算出したギャップ統計量はgap.ward.carsのTabという項目に入っています。

この値を用いて縦軸にギャップ統計量、横軸にクラスタ数の折れ線グラフを作成してみます。

gap <- gap.ward.cars$Tab %>%
# ggplotで可視化するために一旦データフレームに変換
as.data.frame %>%
# k列としてクラスタ数を表す列を追加
mutate(k = seq(k.max))
p <- ggplot(data = gap, aes(x = k, y = gap)) +
geom_line() +
geom_point() +
scale_x_discrete()
print(p)

ギャップ統計量の算出結果

上記のグラフを見ると、k=3, k=4の間でギャップ統計量が急激に低下していることが確認できるかと思います。なので、この場合のクラスタ数はk=3とするのが良いと考えられます。

clusGap関数について

先ほどclusGap関数を用いてギャップ統計量を算出しましたが、こちらの関数の引数について少し解説をしておきます。

x引数

各データの座標を行列またはデータフレームで指定。

行方向にデータ、列方向に座標を並べておくこと。

FUNcluster引数

クラスタリングを実行する関数を指定します。この関数の第一引数に各データの座標の行列またはデータフレームを指定、第二引数にクラスタ数を受け取るように定義します。

get.cluster_id <- function(x, k) {
# データ間の距離の算出
dist.x <- dist(x)
# ward法による階層的クラスタリングの実行
hc.x <- hclust(dist.x, method = "ward.D2")
# 各データのクラスタ番号の算出
ct.x <- cutree(hc.x, k = k)
list(cluster = ct.x)
}

K.max引数

クラスタ数の最大数を指定します。ただし、指定する値は2以上である必要があります。

参考