字符串距离指标有利于子字符串和单词顺序无关?

时间:2015-03-14 09:33:38

标签: r string edit-distance stringdist

对于我的数据分析问题,我通常需要管理名称,名称A和B,我认为它们相同或非常相似,如果A和B共享大量公共子串,无论那些子串的顺序。

例如,对于" COLD"和c(" FLOOD"," COLD / WIND CHILL"),我想选择& #34; COLD / WIND CHILL"更像是" COLD"与" FLOOD"。

我目前的任务是在R.所以我的具体问题如下:

  1. R中是否已定义此类指标?

  2. 是否有可能提供我自己的实现并以某种方式与R的stringdist包集成?

  3. 根据我的要求,我可以简单地使用正则表达式搜索,只要我能在A中找到B或B中的A,我可以认为它们的距离为0.

    非常感谢!

    编辑:

    在以下情况中:

    > vv <- c("FLOOD", "COLD/WIND CHILL")
    > sapply(vv, adist, y = "COLD")
              FLOOD COLD/WIND CHILL 
                  3              11 
    

    我希望距离&#34; COLD&#34;到&#34; COLD / WIND CHILL&#34;会小于&#34; COLD&#34;到&#34;洪水&#34;。

    在找到匹配的子字符串后,似乎必须忽略要删除的剩余部分。

    Edit1:

    我原来的问题已经解决了。以下是在R:

    中使用amatch stringdist的相关问题的跟进

    在我看来,我无法在adist的同一个包中复制stringdist甚至amatch的等效结果。

    以下是插图:

    vv <- c("FLOOD", "COLD/WIND CHILL")
    sapply(vv, adist, y = "COLD",costs=list(deletions=0))
              FLOOD COLD/WIND CHILL 
                  2               0 
    
        stringdist("COLD", c("FLOOD", " COLD/WIND CHILL"), method = 'lv', weight=c(0.001, 0.99, 0.99, 0.99))
    [1] 1.981 1.002
    
    amatch("COLD", c("FLOOD", " COLD/WIND CHILL"), method = 'lv', weight=c(0.0001, 0.999, 0.999, 0.999), maxDist = 100)
    [1] 1
    

    在上述情况下,通过使用stringdist的计算,amatch应该返回2,而不是1

    基于stringdist的文档,

    &#34;重量:
    对于方法=&#39; osa&#39;或者&#39; dl&#39;,按顺序删除,插入,替换和转置的惩罚。当method =&#39; lv&#39;时,忽略转置惩罚。 &#34;

    我已相应地选择了权重以删除对删除的惩罚,同时将惩罚最大化到其他操作。令人鼓舞的是,stringdist显示了权重设置的预期行为。

    我假设amatch会使用stringdist进行计算,但似乎很奇怪amatch的行为与stringdist的行为相矛盾!

    我希望amatch正常工作,以便我不必使用adiststringdist重新实施它。

    再次感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

这是一个追求的方向。基本上,它打算将你的文本分解为三元组(三个字母的序列),并在每个三元组和其他三元组之间返回关联,如果它们达到你设置的级别(这里,0.8)。故障是这个代码只在单词级别工作,而不是像它应该的那样在三元组工作。也许如果文本文件较大,会有区别吗?

library(tm)
library("RWeka")
text <- c("FLOOD", "COLD/WIND CHILL", "OLD", "FRIGID", "FLOW") 

BigramTokenizer <- function(x) NGramTokenizer(x, Weka_control(min = 3, max = 3))

corpus <- Corpus(VectorSource(text))

tdm <- TermDocumentMatrix(corpus, control = list(tokenize = BigramTokenizer))

lapply(tdm$dimnames$Terms, function(x) findAssocs(tdm, x, 0.8))

答案 1 :(得分:1)

您可以将adist用于模糊距离。距离是一个广义的Levenshtein距离。

vv <- c("COLD","FLOOD")
sapply(vv,adist,y="COLD/WIND CHILL")
## COLD FLOOD   
##  11    13    ## the distance to COLD < distance to FLOOD
OP更新后

编辑:

您可以使用costs参数来设置如何根据以下方式计算距离:删除,替换,插入。例如:

sapply(vv, adist, y = "COLD",costs=list(deletions=0))
  FLOOD COLD/WIND       CHILL 
          2               0