5

データ フレームから加重ユークリッド距離を使用して距離行列を作成したいと思います。重みはベクトルで定義されます。次に例を示します。

library("cluster")

a <- c(1,2,3,4,5)
b <- c(5,4,3,2,1)
c <- c(5,4,1,2,3)
df <- data.frame(a,b,c)

weighting <- c(1, 2, 3)

dm <- as.matrix(daisy(df, metric = "euclidean", weights = weighting))

私はどこでも検索しましたが、R でこれに対するパッケージまたはソリューションを見つけることができません。通常のユークリッド。距離。

スタックオーバーフローのアイデアはありますか?

4

1 に答える 1

7

最初に各列にそれぞれの重みの平方根を掛けることで、@ WalterTross のスケーリング手法を使用できます。

newdf <- sweep(df, 2, weighting, function(x,y) x * sqrt(y))
as.matrix(daisy(newdf, metric="euclidean"))

しかし、ユークリッド距離とは何かをより詳細に制御して理解したい場合に備えて、カスタム関数を作成できます。注意として、別の重み付け方法を選択しました。:

xpand <- function(d) do.call("expand.grid", rep(list(1:nrow(d)), 2))
euc_norm <- function(x) sqrt(sum(x^2))
euc_dist <- function(mat, weights=1) {
  iter <- xpand(mat)
  vec <- mapply(function(i,j) euc_norm(weights*(mat[i,] - mat[j,])), 
                iter[,1], iter[,2])
  matrix(vec,nrow(mat), nrow(mat))
}

daisy関数に対してチェックすることで、結果をテストできます。

#test1
as.matrix(daisy(df, metric="euclidean"))
#          1        2        3        4        5
# 1 0.000000 1.732051 4.898979 5.196152 6.000000
# 2 1.732051 0.000000 3.316625 3.464102 4.358899
# 3 4.898979 3.316625 0.000000 1.732051 3.464102
# 4 5.196152 3.464102 1.732051 0.000000 1.732051
# 5 6.000000 4.358899 3.464102 1.732051 0.000000

euc_dist(df)
#          [,1]     [,2]     [,3]     [,4]     [,5]
# [1,] 0.000000 1.732051 4.898979 5.196152 6.000000
# [2,] 1.732051 0.000000 3.316625 3.464102 4.358899
# [3,] 4.898979 3.316625 0.000000 1.732051 3.464102
# [4,] 5.196152 3.464102 1.732051 0.000000 1.732051
# [5,] 6.000000 4.358899 3.464102 1.732051 0.000000

私が Walter の方法を疑う理由は、第一に、重みが平方根によって適用されるのを見たことがないから1/wです。次に、重みを関数に適用すると、別の結果が得られます。

euc_dist(df, weights=weighting) 
于 2016-08-31T03:49:31.053 に答える