2016-08-30 59 views
3

データフレームからのユークリッド距離を重み付けした距離行列を作成したいと考えています。重みはベクトルで定義されます。ここでは例です:重み付きユークリッド距離R

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.ザ・「デイジー」関数にこれをパッケージまたは解決策を見つけることはできませんが、重みドン適用されていないようだし、それはただのユークラッドを吐き出すだけだ。距離。

任意のアイデアStack Overflow?

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

しかし、念のためにあなたがより多くの制御と理解を持っているしたいと思います:

+0

https://stat.ethz.ch/R-manual/R-devel/library/cluster/html/daisy.html 私は実際には、誤解されている場合があります。この文書では、重み付けはGower距離でしか動作しないと言われています。それにもかかわらず、私の質問はまだ立っています:重み付きユークリッド距離をサポートするパッケージはありますか? – Gary866

+0

「重み付き距離」の式を表示する必要があると思います。 –

+0

http://images.slideplayer.com/16/5203007/slides/slide_49.jpg したがって、私が修正した例では、1行目と2行目の間の距離を計算すると、次のように計算されます。 距離= 1 *(1-2)^ 2 + 2 *(5-4)^ 2 + 3 *(5-4)^ 2 距離の計算は、変数と重み付けは実行ごとに異なります。だから、自分の機能を書くだけのシンプルなものではありません。 – Gary866

答えて

3

まず、それぞれの重さの平方根で各列を乗じてスケーリングの@WalterTross'技術を使用することができますユークリッド距離が何であるのか、私たちはカスタム関数を書くことができます。注意として、私は別の重み付け方法を選択しました。 :

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 

私はそれがだ、まず、私は彼らの平方根で適用される重みを見たことがないので、ウォルターの方法がある疑う理由通常1/wです。第二に、自分の体重を私の機能に適用すると、私は別の結果を得ます。

euc_dist(df, weights=weighting) 
+0

複数の重み付け方法があります。私はウェイトをw倍にするためにすべての軸を 'w 'でスケーリングしました。マンハッタンの場合、これは明らかに望ましい効果をもたらす。ユークリッドは正方形を取りますが、それは '(w *(x_i-y_i))^ 2'をしていないと言っていますか?私にとって、これは最も驚きの重みづけスキームであるようです。 –

+0

@ Anony-Mousseあなたは正しいです、私はまた、その平方根ではなく、その重さによってすべての軸をスケーリングしました。ユークリッド距離は平方デルタの和の平方根であるため、事実OPは距離に関する誤った定義を使用しています。私はそれに固執していましたが、それは私に体重の平方根を導入させましたが、それは悪い考えです。 –

+0

二重ユークリッド距離(平方デルタの二乗和)は、計算上重い平方根抽出ステップを節約するため、比較が必要な場合にはもちろん便利ですが、標準ユークリッドメトリックでは重みを定義したままにしておく必要があります。 BTWユークリッド距離とマンハッタン距離は、すべての次元のデルタが0である場合には等しくなります。 –

関連する問題