【问题标题】:Optimize my own distance function in R在 R 中优化我自己的距离函数
【发布时间】:2012-10-05 17:50:55
【问题描述】:

我正在尝试为我的数据创建一个新的距离函数。但是,与 stats 包中的 dist 函数相比,我的代码的性能非常慢。例如,查看欧几里得距离的结果:

mydist = function (x){

  euclidean = function (a, b){
    sqrt(sum((a-b)^2))
  }

  distances = matrix(0, nrow=nrow(x), ncol=nrow(x))
  for (i in 1:nrow(x))
    for (j in 1:(i-1)){  # <- corrected this
      if (j > 0){
         distances[i,j]=euclidean(x[i,], x[j,])
         distances[j,i]=distances[i,j]
      }
    }

  distances
}


m=matrix(1:800, ncol=2)
system.time(as.dist(mydist(m)))
  usuário   sistema decorrido 
    0.714     0.000     0.716      # <- updated values with corrected version

system.time(dist(m))
  usuário   sistema decorrido 
    0.004     0.000     0.002 

我不会使用欧式距离。例如,我正在开发一个新的,它使用一些特定于我的数据的统计数据更加复杂,与代理包的统计数据不同。我在数据集中有数百个变量和数千个示例(行)。不能等待几个小时只是为了计算距离。

我尝试了另一种使用外部应用的代码。它比两个循环快,但仍然很慢。有人可以提出任何建议吗?

【问题讨论】:

  • 除非您使用一些全新的距离度量标准,否则您最好在 Wikipedia 上窥探。 R 和/或 C 中有很多指标函数,它们的现有代码。您的距离函数实际上是时间瓶颈吗?这也是您在选择将其应用于数据集的方法之前应确定的内容。

标签: r function distance


【解决方案1】:

关键是从整个矩阵中减去每一行,而不是每一行。由于减法是按列进行的,因此只需转置矩阵即可。

m=matrix(1:800, ncol=2)
system.time(a<-as.dist(mydist(m)))
# user  system elapsed
# 1.32    0.00    1.32 

t.m<-t(m)
system.time(x<-as.dist(apply(m,1,function(x) sqrt(colSums((x - t.m)^2)))))
# user  system elapsed
# 0.04    0.00    0.03 

any(x!=a) # FALSE

但如果你真的想要速度,你应该使用 C 库。

【讨论】:

  • @user1348438:我知道这里的欧几里得函数只是对其他函数的最小替代?你能澄清一下吗?
【解决方案2】:

加快速度的关键是

  • 您的距离函数可以很容易地向量化。如果是这种情况,请查看? outer 和/或? rep
    这种方法可能非常快,但也很消耗内存。

  • apply 将基本上将两个循环简化为一个,但真正的向量化通常要快得多。

  • 或者你可能想使用例如内联 C 代码,请参阅包内联。

  • 您不小心计算出所需距离的两倍(您进行了对称复制,但 ij 都在整个 1 : nrow (x) 上循环)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-09-15
    • 1970-01-01
    • 1970-01-01
    • 2016-10-21
    • 1970-01-01
    • 1970-01-01
    • 2013-04-30
    • 1970-01-01
    相关资源
    最近更新 更多