距離行列から重心間の距離を計算する効率的な方法


8

n点間の2乗ユークリッド距離正方対称行列と、点のクラスターまたはグループメンバーシップ(クラスター)を示すベクトルがあるとします。クラスタはポイントで構成される場合があります。Dk1

何が最も効率的か(速度の点で)本当に効率的な方法クラスタ重心間の計算距離ここでは?

これまでのところ、私は常にこの状況で主座標分析を行いました。PCoA、またはTorgersonのMDSは、最初にをスカラー積の行列( "double centering")に変換してから、そのPCAを実行することになります。このようにして、それらがまたがるユークリッド空間の点の座標を作成します。その後は、データを使用する場合と同じように、重心間の距離を通常の方法で簡単に計算できます。PCoAは対称正準半定固有分解またはSVDを実行する必要がありますが、S n S nDSgrouped points x variablesn x nSかなり大きくなる可能性があります。さらに、このタスクは次元削減ではなく、実際にはこれらの直交する主軸は必要ありません。だから私はこれらの分解が行き過ぎかもしれないと感じています。

だから、あなたは潜在的に高速な方法についての知識やアイデアを持っていますか?

回答:


6

x1,x2,,xnRdIJ

c=1||Σバツ cJ=1|J|ΣjJバツj

||ccJ||2Dj=||バツバツj||2

ANOVA計算で平方和を分解するのとまったく同じように、代数的恒等式は

||ccJ||2=1|||J|SSJ||+|J|1||SS+1|J|SSJ

SS、すべての点間の距離の二乗の面でこれを再表現します:

SSK=12ΣjK||バツバツj||2=Σ<jKDj

O||+|J|2kO2/k2D


R これらの計算を説明およびテストするためのコードを次に示します。

ss <- function(x) {
  n <- dim(x)[2]
  i <- rep(1:n, n)
  j <- as.vector(t(matrix(i,n)))
  d <- matrix(c(1,1) %*% (x[,i] - x[,j])^2 , n) # The distance matrix entries for `x`
  sum(d[lower.tri(d)])
}
centroid <- function(x) rowMeans(x)
distance2 <- function(x,y) sum((x-y)^2)
#
# Generate two clusters randomly.
#
n.x <- 3; n.y <- 2
x <- matrix(rnorm(2*n.x), 2)
y <- matrix(rnorm(2*n.y), 2)
#
# Compare two formulae.
#
cat("Squared distance between centroids =",
    distance2(centroid(x), centroid(y)),
    "Equivalent value =", 
    (ss(cbind(x,y)) - (n.x + n.y) * (ss(x)/n.x + ss(y)/n.y)) / (n.x*n.y),
    "\n")

パーフェクト!私は自分が自分の仕事へのリンクをはっきりと見ることができず、公式を推定することができない平行四辺形のアイデンティティを知っていたとしても、告白しなければなりません。本当にありがとうございます。任意の数の重心の数式に基づいて(SPSSで)関数を既にプログラムしましたが、PCoAを介した間接的な方法よりも大きな行列Dの方が確かに高速です。
ttnphns

グループ/クラスターがオブジェクトの構成と交差する場合でも、式は有効なままであることも付け加えておきます。
ttnphns

はい、それは正しいです。私が使用するIDは、クラスターが互いに素であるとは想定していません。
whuber

レイトリンクを追加するだけです。上記の関数に基づいたマトリックス表記のメソッドです。stats.stackexchange.com/a/237811/3277
ttnphns

1
K{12}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.