【问题标题】:String distance metrics that is in favor of substring, and word order independent?有利于子字符串且与词序无关的字符串距离度量?
【发布时间】:2015-05-16 19:57:50
【问题描述】:

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

例如,对于“COLD”和 c(“FLOOD”,“COLD/WIND CHILL”),我想选择“COLD/WIND CHILL”,使其更类似于“COLD”而不是“洪水”。

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

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

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

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

非常感谢!

编辑:

在以下情况下:

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

我希望从“COLD”到“COLD/WIND CHILL”的距离小于从“COLD”到“FLOOD”的距离。

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

编辑1:

我原来的问题已经解决了。以下是在 R 中使用 stringdistamatch 的相关问题:

在我看来,我无法重现与adist 相同的结果,甚至无法在与amatch 相同的包中重现stringdist

下图为:

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的文档,

“重量:
对于 method='osa' 或 'dl',按顺序删除、插入、替换和转座的惩罚。当 method='lv' 时,转置的惩罚被忽略。 "

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

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

我希望让amatch 工作,这样我就不必使用adiststringdist 重新实现它。

再次感谢您的帮助。

【问题讨论】:

    标签: r string edit-distance stringdist


    【解决方案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))
    

    【讨论】:

      【解决方案2】:

      您可以使用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 
      

      【讨论】:

      • 对不起,我在我的上下文中尝试过,它仍然不能解决我的问题。请在上面查看我的编辑。
      猜你喜欢
      • 2012-07-25
      • 2018-11-04
      • 2018-09-21
      • 2012-05-18
      • 2011-05-11
      • 1970-01-01
      • 2021-07-15
      • 1970-01-01
      相关资源
      最近更新 更多