2

我有一个 >800k 行的数据集(示例):

id     fieldA       fieldB              codeA   codeB
120    Similar one  addrs example1      929292  0006
3490   Similar oh   addrs example3      929292  0006
2012   CLOSE CAA    addrs example10232  kkda9a  0039
9058   CLASE CAC    addrs example01232  kkda9a  0039
9058   NON DONE     addrs example010193 kkda9a  0039
48848  OOO AD ADDD  addrs example18238  uyMMnn  8303

字段ID是唯一的ID,字段codeA和codeB必须相同,但字段fieldA和fieldB需要Levenshtein距离或类似函数。我需要基于此找到哪些行非常相似。输出可能是以下内容:

   codeA    codeB Similar
   929292   0006  120;3490
   kkda9a   0039  2012;9058
   kkda9a   0039  9058
   uyMMnn   8303  48848

如果我有 2 个约束,如 codeA 和 codeB,那么这么大的数据集的距离矩阵将不起作用并且没有多大意义。我猜一种方法是一个 plyr 函数,由 codeA-codeB 分割,但在那之后我被困住了

为了澄清起见,我想将在 fieldA 和 fieldB 中具有高度相似性并且在 codeA 和 codeB 中具有完全匹配的所有组合在一起。


编辑:

遵循 David DeWert 的想法,沿着这条线的东西似乎适用于每个 codeA-codeB 组,不是一个好的输出 put 似乎是朝着正确的方向迈出的一步:

library(stringdist)
clustering<-function(x){
  if(nrow(x)>1){{d<-stringdistmatrix(paste(x$fieldA,x$fieldB),paste(x$fieldA,x$fieldB),method = "qgram")
  rownames(d)<-x$id
  hc <- hclust(as.dist(d))
  #I need to evaluate correctly this cutting
  res<-cutree(hc,h=5)
  #This returns a list, one element for each cluster found and a named vector inside with the elements
  return(res)
  }else{
  res<-1
  names(res)<-x$id
  return(res)
  }
}

现在我需要找到一种方法将数据帧拆分为 codeA-codeB 组并将此函数应用于它们。


编辑2:

我使用之前的函数集群和 plyr 包管理了一个“足够好”的方法。

result<-dlply(testDF,.(codeA,codeB),clustering)

这将创建一个列表,其中包含“按 codeA、codeB 分组”中的每一个,例如:

$`929292.0006`
 120 3490 
   1    1 

$kkda9a.0039
2012 9058 9058 
   1    1    2 

$uyMMnn.8303
48848 
    1 

attr(,"split_type")
[1] "data.frame"
attr(,"split_labels")
   codeA codeB
1 929292  0006
2 kkda9a  0039
3 uyMMnn  8303

它有效地通过 fieldA 和 fieldB 聚集由 codeA 和 codeB 创建的组。这没有得到我想要的输出,但由于我无法获得更好的解决方案,所以必须这样做。我对此最大的抱怨是 plyr 函数的性质不允许我按组获得超过 1 行(这是完全有意义的),因此我必须使用列表而不是数据框,这不是一个真正的问题。当数据集非常大(像这样)并且 plyr 不能很好地与它们一起工作时,就会出现问题......并且替代 dplyr 包与列表结果不兼容......哦,好吧。

4

1 回答 1

4

创建一个名为“codeAB”的新字段,以根据 codeA-codeB 匹配对数据进行分区,如下所示:

data$codeAB <- factor(apply( data[ , c(4,5) ] , 1 , paste , collapse = "-" ))

然后将每个levels(data$codeAB) 与 Damerau-Levenshtein 聚类。人们似乎在建议 ELKI http://en.wikipedia.org/wiki/ELKI擅长在不构建距离矩阵的情况下对大量数据进行聚类。

有人还问关于 ELKI 中的 DL 指标: Clustering string data with ELKI

我希望这有帮助。

于 2015-02-11T19:02:32.520 回答