2

我有两个矩阵 A 和 B。两者都包含一个名称列表。问题基于相似性度量。我找到 A 的元素与 B(整个矩阵)的最小距离。如果汉明距离大于 3,然后将数据添加到矩阵 B 中,否则不添加。所以让我给你举个例子

 A<-c("cvombiflam","combiflam")
 A<-as.matrix(A)

 B<-c("windfall","computer","baseball")
 B<-as.matrix(B)

现在 A1 将搜索 B 并找到 B 中关于汉明距离最近的成员。最近的是 B2。它将找到与 B[2] 的距离。由于最近距离大于 3,因此 cvomiflam 将添加到 B。现在 B 将是

 B<-c("windfall",
      "computer",
      "baseball",
      "cvombiflam")

现在 A("combiflam") 的第二个元素将搜索 B。最接近的是 B 的第四个元素 (cvombiflam ),距离为 1。因此 combiflam 不会添加到 B 中。我想更新最终的 B 列表

我写的代码是:

 for(i in 1:length(A))
 {    
      d<-min(stringdistmatrix(A[i],B)
      if(d>3)
      {            
           B<-rbind(B,A[i])
      }
 }   

现在我有一个大约 140,000 的矩阵和 200,000 的 B。代码运行良好,但运行需要很长时间。请告诉我一个更快的方法来做到这一点。

4

2 回答 2

1

而不是B一遍又一遍地增长,这很昂贵并且最终可能会分割你的内存空间,你可以只存储和更新一个向量TRUE或指示是否应该添加FALSE一个元素。然后,仅在最后,将这些选定的元素附加到.ABB

另一件需要注意的事情是,当您只需要向量时,您在任何地方都使用矩阵。我为你修好了。

A <- as.vector(A)
B <- as.vector(B)

add.A <- rep(FALSE, length(A))

for(i in 1:length(A)) {
  if (i %% 1000L == 0L) cat(sprintf("%.2f percent completed", 100 * i / length(A)))
  d.B <- stringdist(A[i], B)
  d.A <- stringdist(A[i], A[add.A])
  d <- min(c(d.B, d.A))
  if (d > 3) {            
    add.A[i] <- TRUE
  }
}

B <- c(B, A[add.A])

正在解决的问题,您的问题维度仍然很大。要计算很多距离(至少 length(A) * length(B)),这将花费很多时间。我cat在循环中添加了一个,让您了解它运行需要多长时间。请试一试并评论它有多慢或多快。

此外,如果AB共同的项目,您最初可以通过执行以下操作来减少问题维度:

A <- unique(A)
B <- unique(B)
A <- setdiff(A, B)
于 2013-09-22T11:51:52.680 回答
0

您的代码建议您B迭代地增长对象 ( B = rbind(B, A[i])。这是非常缓慢的,因为内存大小要求不断增长B。不断扩展B内存需要很长时间,导致循环变得非常慢。你可以做一些事情来解决这个问题:

  • 在循环之前预分配B到正确的大小并将其填充到循环中。
  • 使用apply样式循环,rbind最后:

    list_of_results = lapply(A, stringdistmatrix, b = B)
    big_data_frame = do.call('rbind', list_of_results)
    

其他加快计算速度的选项:

  • 使用多个核心,请ncores参阅stringdistmatrix.
  • 尝试不同的距离度量(method参数),看看是否会有所不同。
于 2013-09-22T11:40:47.813 回答