【问题标题】:create distance matrix for strings为字符串创建距离矩阵
【发布时间】:2019-05-02 23:51:19
【问题描述】:

我想加快下面的代码。有人能这么好心并提出一些建议吗?

library(dplyr)
library(fuzzywuzzyR)

set.seed(42)
rm(list = ls())
options(scipen = 999)

init = FuzzMatcher$new()

data <- data.frame(string = c("hello world", "hello vorld", "hello world 1", "hello world", "hello world hello world"))
data$string <- as.character(data$string)

distance_function <- function(string_1, string_2) {
    init$Token_set_ratio(string1 = string_1, string2 = string_2)
}

combinations <- combn(nrow(data), 2)
distances <- matrix(, nrow = 1, ncol = ncol(combinations))

distance_matrix <- matrix(NA, nrow = nrow(data), ncol = nrow(data), dimnames = list(data$string, data$string))

for (i in 1:ncol(combinations)) {

    distance <- distance_function(data[combinations[1, i], 1], data[combinations[2, i], 1])

    #print(data[combinations[1, i], 1])
    #print(data[combinations[2, i], 1])
    #print(distance)

    distance_matrix[combinations[1, i], combinations[2, i]] <- distance
    distance_matrix[combinations[2, i], combinations[1, i]] <- distance

}

distance_matrix

顺便说一句,我尝试使用 proxy::dist 和其他各种方法都没有成功。我也不认为字符串距离函数按预期工作,但这是另一回事。

最终,我想使用距离矩阵来执行一些聚类来对相似的字符串进行分组(与词序无关)。

【问题讨论】:

  • 您能否介绍一下需要更多时间的地方。如果是 distance_function 需要更多时间,那么当前设置会很困难
  • 不确定如何执行此操作,但也许循环可以更改为应用?抱歉还是个R处女
  • 您可以使用profvis。检查here
  • 谢谢 - 很高兴知道 - 会试一试,但不确定这是否仅适用于我不使用的 r studio ...
  • 如果proxy::dist 对您来说仍然太慢,那么您可能必须在 C 或 C++ 中实现自己的函数。我最近展示了一个使用地理距离的example with multi-threading,但您可以调整它以支持字符串并输出完整的矩阵。还要检查this example

标签: r


【解决方案1】:

如果你想要一个矩阵,你可以使用stringdist 包。据我所知,您使用的包计算了 Levenshtein 距离,因此我包含了method = "lv"(您也可以尝试其他方法)。如果您有问题,或者是否首选矩阵以外的格式,请告诉我。此外,您可以考虑使用 Levenshtein Distance 以外的方法(即,在 4 个字母的单词中更改 2 与在 20 个单词的句子中更改 2 看起来相同)。祝你好运!!!

library(dplyr)
library(stringdist)

set.seed(42)
rm(list = ls())
options(scipen = 999)

data <- data.frame(string = c("hello world", "hello vorld", "hello world 1", "hello world", "hello world hello world"))
data$string <- as.character(data$string)

dist_mat <- stringdist::stringdistmatrix(data$string, data$string, method = "lv")

rownames(dist_mat) <- data$string
colnames(dist_mat) <- data$string

dist_mat
                        hello world hello vorld hello world 1 hello world hello world hello world
hello world                       0           1             2           0                      12
hello vorld                       1           0             3           1                      13
hello world 1                     2           3             0           2                      11
hello world                       0           1             2           0                      12
hello world hello world          12          13            11          12                       0

【讨论】:

  • 谢谢我知道 stringdist 但 lv 不够好 - 请参阅 Token_set_ratio。因此我从头开始实施......
  • 啊,我明白了,我第一次看的时候没听懂。道歉!当我运行你的代码时,它给了我一个NA 的矩阵,所以我无法检查输出。我无法理解Token_set_ratio。我仍然无法让它为我工作,但它可能是我缺少的一些简单的东西。您能否解释一下为什么您更喜欢它而不是其他距离度量(即为什么它最适合您的数据)。看起来它提取了字母数字字符,形成了相交字符与剩余字符的比率。那么,“绿色”和“流派”会是绝配吗?
  • 您在问题中提到了 apply 系列。如果它的工作方式与常规字符串距离的工作方式相同,您始终可以使用sapply,它会为此输出一个矩阵。例如(使用stringdist):sapply(data$string, stringdist, data$string, method = "lv")
猜你喜欢
  • 1970-01-01
  • 2015-06-11
  • 2021-08-23
  • 1970-01-01
  • 2016-09-22
  • 2020-09-11
  • 2021-10-01
  • 2016-05-19
  • 2019-07-13
相关资源
最近更新 更多