具有多个字符串的字符串中每个元素的最佳匹配

时间:2019-03-17 14:43:13

标签: r analytics data-manipulation

输入数据:

a <- c("coca cola","hot coffee","Running Shoes","Table cloth",
       ”mobile phones under 5000”,”Amazon kindle”)
b <- c("running shoes","plastic cup","pizza","Let’s go to hill","motor van",
       "coffee table","drinking coffee on a rainy day",”Best mobile phones under 10000”,
       ”kindle e-books”,”Coffee Cup”)

将向量中每个句子的每个单词(此处为向量a)与单独的向量(此处为向量b)中的所有字符串逐字匹配,以获得最佳匹配。

The expected output

逻辑: 向量“ a”的所有句子必须与向量“ b”的所有句子逐字匹配,并且必须计算百分比。 向量“ a”的每个句子只能有一个最佳匹配。

示例1:向量“ a”中的“跑鞋”与向量“ b”中的“跑鞋”完全匹配,并且percentage_match为100%(因为两个词都匹配)

示例2:“热咖啡”的最佳匹配可能是“在下雨天喝咖啡”或“咖啡桌”或“咖啡杯”,而且百分比匹配为50%(因为只有“咖啡”与在所有情况下均为“热咖啡”)。在这种情况下,如果有多个竞争者具有相同的最大percentage_match,我们将选择字符串长度最小的最佳匹配项,即“咖啡桌”和“咖啡杯”的优先级高于“在雨天喝咖啡”的优先级天”。即使这样做了,还是有关系的,我们可以自由选择任何东西(即“咖啡桌”或“咖啡杯”中的任何一个,都可以最适合“热咖啡”。

尝试过的代码:

as <- strsplit(a, " ")
bs <- strsplit(b, " ")

matchFun <- function(x, y) length(intersect(x, y)) / length(x) * 100
mx <- outer(as, bs, Vectorize(matchFun))

m <- apply(mx, 1, which.max)  # the maximum column of each row

z <- unlist(apply(mx, 1, function(x) x[which.max(x)]))  # maximum percentage
z[z == 0] <- NA  # this gives you the NA if you want it

data.frame(a, Matching_String=b[m], match_perc=z)

面临的问题:由于我的实际数据非常大(超过200万条记录要与1百万条记录匹配),所以这段代码永远用不完。

1 个答案:

答案 0 :(得分:0)

这是使用软件包stringdistmatrix中的stringdist来执行此操作的一种方法。基本上,我们正在计算ab中的字符串之间的距离。然后我们保持最小距离。即使距离很大,也总会有一场比赛。您可以做的一件事是确定最小距离,否则确定为NA。

library(stringdist)
m <- stringdistmatrix(tolower(a), tolower(b), method = "qgram")
b[apply(m, 1, which.min)]

#[1] "plastic cup"                    "coffee table"                   "running shoes"                 
#[4] "coffee table"                   "best mobile phones under 10000" "kindle e-books"