k-meansでバイナリ変数(値0および1)を使用する必要があります。ただし、k-meansは連続変数でのみ機能します。一部の人々は、k-meansが連続変数に対してのみ設計されているという事実を無視して、k-meansでこれらのバイナリ変数をまだ使用していることを知っています。これは私には受け入れられません。
質問:
- それでは、k-means /階層的クラスタリングでバイナリ変数を使用する統計的/数学的に正しい方法は何ですか?
- SAS / Rでソリューションを実装する方法は?
k-meansでバイナリ変数(値0および1)を使用する必要があります。ただし、k-meansは連続変数でのみ機能します。一部の人々は、k-meansが連続変数に対してのみ設計されているという事実を無視して、k-meansでこれらのバイナリ変数をまだ使用していることを知っています。これは私には受け入れられません。
質問:
回答:
混合型のデータを使用してk-meansクラスタリングを実行しないでください。k-meansは本質的に、クラスター化された観測値とクラスター重心の間のクラスター内のユークリッド距離を最小化するパーティションを見つけるための単純な検索アルゴリズムであるため、ユークリッド距離の二乗が意味を持つデータでのみ使用する必要があります。
この時点で、元のデータマトリックスを必要とせずに、距離マトリックスで操作できるクラスタリング手法を使用できます。(k-meansには後者が必要であることに注意してください。)最も一般的な選択肢は、medoid(PAM、k-meansと本質的に同じですが、重心ではなく最も中心的な観測値を使用)の周りのパーティション分割、さまざまな階層クラスタリングアプローチ(例: 、中央値、単一リンケージ、完全リンケージ。階層クラスタリングでは、最終的なクラスター割り当てを取得するために「ツリーをカットする」場所を決定する必要があります)、およびより柔軟なクラスター形状を可能にするDBSCAN。
以下に簡単なR
デモを示します(実際には3つのクラスターがありますが、データはほとんど2つのクラスターが適切であるように見えます)。
library(cluster) # we'll use these packages
library(fpc)
# here we're generating 45 data in 3 clusters:
set.seed(3296) # this makes the example exactly reproducible
n = 15
cont = c(rnorm(n, mean=0, sd=1),
rnorm(n, mean=1, sd=1),
rnorm(n, mean=2, sd=1) )
bin = c(rbinom(n, size=1, prob=.2),
rbinom(n, size=1, prob=.5),
rbinom(n, size=1, prob=.8) )
ord = c(rbinom(n, size=5, prob=.2),
rbinom(n, size=5, prob=.5),
rbinom(n, size=5, prob=.8) )
data = data.frame(cont=cont, bin=bin, ord=factor(ord, ordered=TRUE))
# this returns the distance matrix with Gower's distance:
g.dist = daisy(data, metric="gower", type=list(symm=2))
PAMを使用して、異なる数のクラスターを検索することから始めます。
# we can start by searching over different numbers of clusters with PAM:
pc = pamk(g.dist, krange=1:5, criterion="asw")
pc[2:3]
# $nc
# [1] 2 # 2 clusters maximize the average silhouette width
#
# $crit
# [1] 0.0000000 0.6227580 0.5593053 0.5011497 0.4294626
pc = pc$pamobject; pc # this is the optimal PAM clustering
# Medoids:
# ID
# [1,] "29" "29"
# [2,] "33" "33"
# Clustering vector:
# 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 26
# 1 1 1 1 1 2 1 1 1 1 1 2 1 2 1 2 2 1 1 1 2 1 2 1 2 2
# 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
# 1 2 1 2 2 1 2 2 2 2 1 2 1 2 2 2 2 2 2
# Objective function:
# build swap
# 0.1500934 0.1461762
#
# Available components:
# [1] "medoids" "id.med" "clustering" "objective" "isolation"
# [6] "clusinfo" "silinfo" "diss" "call"
これらの結果は、階層クラスタリングの結果と比較できます。
hc.m = hclust(g.dist, method="median")
hc.s = hclust(g.dist, method="single")
hc.c = hclust(g.dist, method="complete")
windows(height=3.5, width=9)
layout(matrix(1:3, nrow=1))
plot(hc.m)
plot(hc.s)
plot(hc.c)
中央値法は2(おそらく3)クラスターを示唆し、単一は2のみをサポートしますが、完全な方法は私の目に2、3または4を示唆します。
最後に、DBSCANを試すことができます。これには、2つのパラメーターを指定する必要があります:eps、「到達可能距離」(2つの観測値をリンクする必要がある距離)、およびminPts(それらを呼び出す前に相互に接続する必要があるポイントの最小数) 'クラスタ')。minPtsの経験則は、次元数よりも1つ多く使用することです(この例では3 + 1 = 4)が、小さすぎる数を使用することはお勧めしません。のデフォルト値dbscan
は5です。それに固執します。到達可能距離について考える1つの方法は、距離の何パーセントが特定の値よりも小さいかを確認することです。そのためには、距離の分布を調べます。
windows()
layout(matrix(1:2, nrow=1))
plot(density(na.omit(g.dist[upper.tri(g.dist)])), main="kernel density")
plot(ecdf(g.dist[upper.tri(g.dist)]), main="ECDF")
距離自体は、視覚的に識別可能な「近く」と「遠く」のグループにクラスター化されているようです。.3の値は、2つのグループの距離を最も明確に区別するようです。さまざまな選択肢のepsに対する出力の感度を調べるには、.2と.4を試してください。
dbc3 = dbscan(g.dist, eps=.3, MinPts=5, method="dist"); dbc3
# dbscan Pts=45 MinPts=5 eps=0.3
# 1 2
# seed 22 23
# total 22 23
dbc2 = dbscan(g.dist, eps=.2, MinPts=5, method="dist"); dbc2
# dbscan Pts=45 MinPts=5 eps=0.2
# 1 2
# border 2 1
# seed 20 22
# total 22 23
dbc4 = dbscan(g.dist, eps=.4, MinPts=5, method="dist"); dbc4
# dbscan Pts=45 MinPts=5 eps=0.4
# 1
# seed 45
# total 45
を使用eps=.3
すると、非常にクリーンなソリューションが得られます。これは、(少なくとも質的には)上記の他の方法から見たものと一致します。
意味のあるクラスター1ネスはないため、異なるクラスター化から「クラスター1」と呼ばれる観測値を一致させるように注意する必要があります。代わりに、テーブルを作成し、あるフィットで「クラスター1」と呼ばれるほとんどの観測値が別のフィットで「クラスター2」と呼ばれる場合、結果は依然として実質的に類似していることがわかります。この場合、さまざまなクラスタリングはほとんど非常に安定しており、毎回同じ観測値を同じクラスターに配置します。完全なリンケージ階層クラスタリングのみが異なります。
# comparing the clusterings
table(cutree(hc.m, k=2), cutree(hc.s, k=2))
# 1 2
# 1 22 0
# 2 0 23
table(cutree(hc.m, k=2), pc$clustering)
# 1 2
# 1 22 0
# 2 0 23
table(pc$clustering, dbc3$cluster)
# 1 2
# 1 22 0
# 2 0 23
table(cutree(hc.m, k=2), cutree(hc.c, k=2))
# 1 2
# 1 14 8
# 2 7 16
もちろん、クラスター分析がデータの真の潜在クラスターを回復するという保証はありません。真のクラスターラベル(たとえば、ロジスティック回帰の状況で利用可能)がないことは、膨大な量の情報が利用できないことを意味します。非常に大きなデータセットであっても、クラスターは完全に回復できるほど十分に分離されていない場合があります。この場合、真のクラスターメンバーシップを知っているので、それを出力と比較して、どれだけうまくいったかを確認できます。前述したように、実際には3つの潜在クラスターがありますが、データは2つのクラスターのように見えます。
pc$clustering[1:15] # these were actually cluster 1 in the data generating process
# 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
# 1 1 1 1 1 2 1 1 1 1 1 2 1 2 1
pc$clustering[16:30] # these were actually cluster 2 in the data generating process
# 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
# 2 2 1 1 1 2 1 2 1 2 2 1 2 1 2
pc$clustering[31:45] # these were actually cluster 3 in the data generating process
# 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
# 2 1 2 2 2 2 1 2 1 2 2 2 2 2 2
median method suggests 2 (possibly 3) clusters, the single only supports 2, but the complete method could suggest 2, 3 or 4
..これにどのように到達しますか?0.3の高さを使用していますか?
Finchによるこのペーパーhttp://www.jds-online.com/files/JDS-192.pdfをご覧ください。バイナリデータに連続法を適用するとデータが不正確にクラスター化される理由と、さらに重要なこととして、適切な距離関数の選択肢を説明しています。k-meansを使用してクラスタリングする方法ではなく、非ユークリッドメトリックとWardのような階層的方法を使用してバイナリデータを適切にクラスタリングする方法については説明しません。