【问题标题】:Closest match of a sentence between two data frames in RR中两个数据帧之间句子的最接近匹配
【发布时间】:2016-03-05 13:39:56
【问题描述】:

我有两个数据框。第一个 - 保存在名为 b 的对象中:

structure(list(CONTENT = c("@myntra beautiful teamä»ç where is the winners list?", 
"The best ever Puma wishlist for Workout freaks, Head over to @myntra  https://t.co/V58Gk3EblW #MyPUMACollection Hit Like if you Find it good", 
"I finalised on buy a top from Myntra, and then I found the same top at 20% off in jabong. I feel like I've achieved so much in life!", 
"Check out #myPUMAcollection on @Myntra. Its perfect for a day at gym.  https://t.co/VeRy4G3c7X https://t.co/fOpBRWCdSh", 
"Check out #myPUMAcollection on @Myntra. Its perfect for a day at gym.  https://t.co/VeRy4G3c7X.....", 
"@DrDrupad @myntra #myPUMAcollection superb :)", "Super exclusive collection @myntra #myPUMAcollection   https://t.co/Qm9dZzJdms", 
"@myntra gave my best Love playing wid u Hope to win  #myPUMAcollection", 
"Check out PUMA Unisex Black Running Performance Gloves on Myntra!  https://t.co/YD6IcvuG98 @myntra  #myPUMAcollection", 
"@myntra i have been mailing my issue daily since past week.All i get in reply is an auto generated assurance mail. 1st time pissed wd myntra"
), score = c(7.129, 7.08, 6.676, 5.572, 5.572, 5.535, 5.424, 
5.205, 4.464, 4.245)), .Names = c("CONTENT", "score"), row.names = c(25L, 
103L, 95L, 66L, 90L, 75L, 107L, 32L, 184L, 2L), class = "data.frame")

第二个数据库 - 保存在一个名为 c 的对象中:

structure(list(CONTENT = c("The best ever for workout  over to myntra like if you find it good", 
"i finalised buy a top  myntra and found the at in feel like i so in life"
)), .Names = "CONTENT", row.names = c(103L, 95L), class = "data.frame")

我想为第二个数据帧(c)中的每条语句找到第一个数据帧(b)中最接近的匹配,并返回第一个数据帧(b)的分数。

例如,语句 The best ever for workout over to myntra like if you find it good 与数据帧 1 中的第二条语句非常匹配,因此我应该返回分数 7.080。

我尝试使用堆栈溢出的代码并进行一些调整:

cp <- str_split(c$CONTENT, " ")
library(data.table)
nn <- lengths(cp)  ## Or, for < R-3.2.0, `nn <- sapply(wordList, length)` 
dt <- data.table(grp=rep(seq_along(nn), times=nn), X = unlist(cp), key="grp")
dt[,Score:=b$score[pmatch(X,b$CONTENT)]]
dt[!is.na(Score), list(avgScore=sum(Score)), by="grp"]

这仅返回来自 df c 的一条语句的值。有人可以帮忙吗?

【问题讨论】:

  • 您是否致力于使用str_split / pmatch 的这种方法来确定给定短语的最佳匹配?因为有适当的模糊匹配算法来处理这种情况,可能会产生更好的结果。
  • @nrussell 不是真的...如果你能告诉我可以部署的模糊匹配算法类型会很有帮助

标签: r string match


【解决方案1】:

这是使用stringdist 包中的stringsim 的一种方法。有几种methods(算法)可供选择——我选择了Jaro distance 度量来计算相似性,因为它似乎为您的数据产生了合理的结果。话虽如此,我对这个主题的体验充其量只是随意,因此您可能需要花一些时间阅读并尝试使用 stringdist 提供的各种算法。


为了减少混乱,我使用这个包装函数返回给定字符串最相似(最高相似值)元素的索引,

library(stringdist)
library(data.table)

best_match <- function(x, y, method = "jw", ...) {
    which.max(stringsim(x, y, method, ...))
}

并使用要匹配的字符串创建data.table,为逐行操作添加虚拟索引:

Dt <- data.table(
    MatchPhrase = df_c$CONTENT,
    Idx = 1:nrow(df_c)
)

使用best_match,添加一个具有最佳匹配索引的列(然后删除虚拟的Idx列),

Dt[, MatchIdx := best_match(df_b$CONTENT, MatchPhrase), 
    by = "Idx"][,Idx := NULL]

并从df_b 中提取相应的元素(我将您的数据从b 和c 分别重命名为df_b 和df_c):

Dt[, .(Score = df_b$score[MatchIdx],
       BestMatch = df_b$CONTENT[MatchIdx]),
   by = "MatchPhrase"]
#                                                                MatchPhrase Score
#1:       The best ever for workout  over to myntra like if you find it good 7.080
#2: i finalised buy a top  myntra and found the at in feel like i so in life 6.676

#                                                                                                                                      BestMatch
#1: The best ever Puma wishlist for Workout freaks, Head over to @myntra  https://t.co/V58Gk3EblW #MyPUMACollection Hit Like if you Find it good
#2:         I finalised on buy a top from Myntra, and then I found the same top at 20% off in jabong. I feel like I've achieved so much in life!

【讨论】:

  • 非常感谢 nrussell....它与示例集完美配合。我将更多地探索如何用我的实际数据集实现这一点。再次感谢您。
  • @nrussell....我确实通过了 Jaro 距离....发现很有趣..感谢您向我介绍模糊匹配算法....以前不知道.. .对我很有帮助。
猜你喜欢
  • 1970-01-01
  • 2012-08-20
  • 1970-01-01
  • 2017-05-09
  • 2021-09-15
  • 1970-01-01
  • 2015-10-27
  • 2020-07-30
  • 1970-01-01
相关资源
最近更新 更多