【问题标题】:Weighted Euclidean Distance in RR中的加权欧几里得距离
【发布时间】:2017-01-07 06:42:08
【问题描述】:

我想创建一个距离矩阵,其中包含与数据框的加权欧几里德距离。权重将在向量中定义。这是一个例子:

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 中找不到包或解决方案。'cluster'包中的'daisy'函数声称支持加权,但似乎没有应用权重,它只是吐出常规的euclid。距离。

任何想法堆栈溢出?

【问题讨论】:

  • stat.ethz.ch/R-manual/R-devel/library/cluster/html/daisy.html 实际上我可能弄错了。该文件似乎说加权仅适用于高尔距离。尽管如此,我的问题仍然存在:是否有支持加权欧几里得距离的包?
  • 我认为您需要显示“加权距离”的公式。
  • images.slideplayer.com/16/5203007/slides/slide_49.jpg 因此,在示例中(我已更正)如果我们想要第 1 行和第 2 行之间的距离,它将计算为:距离 = 1*(1-2)^2 + 2*(5-4)^2 + 3*(5-4)^2 距离计算将应用于大型数据集,其中变量和权重的数量在每次运行时都会有所不同。因此,仅仅编写自己的函数并不是那么简单(或至少高于我的技能水平),因此我正在寻找一个包。
  • 好像别人自己写的函数。您可能可以尝试重新创建。
  • 您可以通过权重的平方根来缩放向量(将每个维度乘以其自己的比例因子,而不是常见的向量运算),然后继续使用欧几里得距离。不过,不知道如何在 R 中做到这一点。

标签: r cluster-analysis euclidean-distance r-daisy


【解决方案1】:

我们可以使用@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) 

【讨论】:

  • 加权方式不止一种。我会通过w 缩放每个轴以将w 乘以权重。对于曼哈顿拳头来说,这显然会产生预期的效果。欧几里得占据了广场,但谁说它没有做(w*(x_i-y_i))^2?对我来说,这似乎是最不意外的加权方案。
  • @Anony-Mousse 你是对的,我也会按每个轴的权重而不是平方根来缩放每个轴。欧几里得距离是平方增量之和的平方根,所以实际上 OP 在他们对他们问题的评论中使用了错误的距离定义。我坚持这一点,这让我引入了权重的平方根,但这是个坏主意。
  • 如果只需要比较,平方欧几里得距离(平方差的总和)当然很有用,因为它节省了计算繁重的平方根提取步骤,但权重应该保持在标准欧几里得度量中定义。 BTW 欧几里得距离和曼哈顿距离是相等的,当所有维度上的增量除一为零时。
  • @Anony-Mousse 我没有在我的文章中明确说明我选择了不同的加权技术。
  • 很棒的帖子,谢谢。缩放方法成功了,我会在某个时候尝试其他技术。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-03-02
  • 2021-01-31
  • 1970-01-01
  • 2015-07-15
  • 2014-02-04
相关资源
最近更新 更多