2016-08-30 141 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)) 

我搜索无处不在,声称支持加权不能“集群”包内发现河的“菊花”功能的软件包或解决方案,这一点,但权重唐似乎没有被应用,它只是吐出常规的欧几里得。距离。

任何想法堆栈溢出?

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 我可能搞错了,其实。该文件似乎表示,权重只适用于高尔距离。尽管如此,我的问题仍然存在:是否有支持加权欧几里德距离的包? – 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 

我怀疑Walter的方法,是因为应用通过它们的平方根首先,我从来没有见过的权重的原因,它是通常为1/w。其次,当我将权重应用于我的功能时,我会得到不同的结果。

euc_dist(df, weights=weighting) 
+0

有多种加权方式。我会用'w'缩放每一个轴来放置'w'倍的重量。对曼哈顿而言,这显然会产生预期的效果。欧几里得占据了方块,但是谁说它没有做'(w *(x_i-y_i))^ 2'?对我而言,这似乎是最令人惊讶的加权方案。 –

+0

@ Anony-Mousse你是对的,我也会通过它的重量而不是其平方根来缩放每个轴。欧几里德距离是平方三角形之和的平方根,所以事实上,OP在他们的问题的评论中使用了距离的错误定义。我坚持这一点,这让我引入权重的平方根,但这是一个坏主意。 –

+0

如果只需要进行比较,那么欧氏距离的平方(三角形的平方和)当然很有用,因为它节省了计算量大的平方根提取步骤,但权重应该在标准欧几里德度量中保持定义。 BTW欧几里德曼和曼哈顿距离在所有维度上的增量相等时都是相等的,但其中一个为零。 –

相关问题