【问题标题】:Similarity scores based on string comparison in R (edit distance)基于 R 中字符串比较的相似度得分(编辑距离)
【发布时间】:2012-07-17 03:34:55
【问题描述】:

我正在尝试根据 2 个字符串之间的比较来分配相似度分数。 R中是否有相同的功能。我知道SAS中有一个名为SPEDIS的功能。请告诉我R中是否有这样的功能。

【问题讨论】:

  • 你探索过adistagrep吗?我不熟悉 SPEDIS。

标签: r string-comparison edit-distance


【解决方案1】:

函数adist 计算两个字符串之间的Levenshtein edit distance。这可以转化为相似性度量 1 - (Levenshtein 编辑距离/更长的字符串长度)。

RecordLinkage 包中的levenshteinSim 函数也直接执行此操作,并且可能比adist 更快。

library(RecordLinkage)
> levenshteinSim("apple", "apple")
[1] 1
> levenshteinSim("apple", "aaple")
[1] 0.8
> levenshteinSim("apple", "appled")
[1] 0.8333333
> levenshteinSim("appl", "apple")
[1] 0.8

ETA:有趣的是,虽然 RecordLinkage 包中的 levenshteinDist 似乎比 adist 稍快,但 levenshteinSim 比两者都慢得多。使用rbenchmark 包:

> benchmark(levenshteinDist("applesauce", "aaplesauce"), replications=100000)
                                         test replications elapsed relative
1 levenshteinDist("applesauce", "aaplesauce")       100000   4.012        1
  user.self sys.self user.child sys.child
1     3.583    0.452          0         0
> benchmark(adist("applesauce", "aaplesauce"), replications=100000)
                               test replications elapsed relative user.self
1 adist("applesauce", "aaplesauce")       100000   4.277        1     3.707
  sys.self user.child sys.child
1    0.461          0         0
> benchmark(levenshteinSim("applesauce", "aaplesauce"), replications=100000)
                                        test replications elapsed relative
1 levenshteinSim("applesauce", "aaplesauce")       100000   7.206        1
  user.self sys.self user.child sys.child
1      6.49    0.743          0         0

这种开销仅仅是因为levenshteinSim 的代码,它只是levenshteinDist 的包装:

> levenshteinSim
function (str1, str2) 
{
    return(1 - (levenshteinDist(str1, str2)/pmax(nchar(str1), 
        nchar(str2))))
}

仅供参考:如果您总是比较两个字符串而不是向量,您可以创建一个使用 max 而不是 pmax 的新版本,并将运行时间缩短约 25%:

mylevsim = function (str1, str2) 
{
    return(1 - (levenshteinDist(str1, str2)/max(nchar(str1), 
        nchar(str2))))
}
> benchmark(mylevsim("applesauce", "aaplesauce"), replications=100000)
                                  test replications elapsed relative user.self
1 mylevsim("applesauce", "aaplesauce")       100000   5.608        1     4.987
  sys.self user.child sys.child
1    0.627          0         0

长话短说 - adistlevenshteinDist 在性能方面几乎没有区别,但如果您不想添加包依赖项,则前者更可取。如何将其转化为相似性度量确实会对性能产生一些影响。

【讨论】:

  • 嗨,是的,该功能很有帮助。另外,是否可以在 sql 查询中直接使用此函数。我正在使用 sqldf 包编写 sql 查询并将其结果分配给 R.example title_score b.id join filterweights c on b.subcategory_id=c.subcategory and c.filter_name='title'");
  • 包“RecordLinkage”已从 CRAN 存储库中删除。 ... 存档于 2020 年 2 月 2 日,因为没有维护者纠正检查错误。
  • 如果我目前必须使用 R 3.6.0,你能推荐一个类似的包吗?不幸的是,adist 和 RecordLinkage 都需要 R 3.6.3。谢谢
猜你喜欢
  • 2018-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-25
  • 2011-10-20
  • 2014-12-23
  • 1970-01-01
相关资源
最近更新 更多