如何测量字符串之间的相似性?

How to measure similarity between strings?

提问人:Sacha Epskamp 提问时间:5/18/2011 最后编辑:zx8754Sacha Epskamp 更新时间:12/5/2018 访问量:8067

问:

我有一堆名字,我想获得唯一的名字。但是,由于拼写错误和数据不一致,名称可能会写错。我正在寻找一种方法来检查字符串向量,如果其中两个是相似的。

例如:

pres <- c(" Obama, B.","Bush, G.W.","Obama, B.H.","Clinton, W.J.")

我想找到它并且非常相似。有没有办法做到这一点?" Obama, B.""Obama, B.H."

正则表达式 字符串 R-FAQ

评论


答:

32赞 Joris Meys 5/18/2011 #1

这可以基于例如Levenshtein距离来完成。在不同的包中,有多种实现。可以在这些问题的答案中找到一些解决方案和软件包:

但大多数情况下会做你想做的事:agrep

> sapply(pres,agrep,pres)
$` Obama, B.`
[1] 1 3

$`Bush, G.W.`
[1] 2

$`Obama, B.H.`
[1] 1 3

$`Clinton, W.J.`
[1] 4
18赞 Chase 5/18/2011 #2

也许这就是你想要的?它使用 Levenshtein 编辑距离搜索近似匹配项。agrep

lapply(pres, agrep, pres, value = TRUE)

[[1]]
[1] " Obama, B."  "Obama, B.H."

[[2]]
[1] "Bush, G.W."

[[3]]
[1] " Obama, B."  "Obama, B.H."

[[4]]
[1] "Clinton, W.J."
0赞 Paul Rougieux 12/5/2018 #3

添加另一个副本以显示它适用于多个副本。

pres <- c(" Obama, B.","Bush, G.W.","Obama, B.H.","Clinton, W.J.", "Bush, G.")

adist 显示 2 个字符向量之间的字符串距离

adist(" Obama, B.", pres)
#      [,1] [,2] [,3] [,4] [,5]
# [1,]    0    9    3   10    7

例如,要选择离您最近的字符串,可以采用距离最小的字符串。为了避免相同的字符串,我只取了大于零的距离:" Obama, B."

d <- adist(" Obama, B.", pres)
pres[min(d[d>0])]
# [1] "Obama, B.H."

若要获取唯一名称,请考虑拼写错误和不一致,可以将每个字符串与所有以前的字符串进行比较。然后,如果有类似的,请将其删除。我创建了一个执行此操作的函数。 然后依次应用于向量的所有元素。keepunique()keepunique()Reduce()

keepunique <-  function(previousones, x){
    if(any(adist(x, previousones)<5)){
        x <- NULL
    }
    return(c(previousones, x))
}
Reduce(keepunique, pres)
# [1] " Obama, B."    "Bush, G.W."    "Clinton, W.J."