计算短语中匹配的单词数
Count number of words match in phrase
我有两大短语列表。我需要检查其他列表中存在的单词的百分比,并从其他列表中获得最佳结果。
A <- data.frame(name = c(
"X-ray right leg arteries",
"x-ray left shoulder",
"x-ray leg arteries",
"x-ray leg with 20km distance"
), stringsAsFactors = F)
B <- data.frame(name = c(
"X-ray left leg arteries",
"X-ray leg",
"xray right leg",
"X-ray right leg arteries"
), stringsAsFactors = F)
fuzzy_prep_words <- function(words) {
words <- unlist(strsplit(tolower(gsub("[[:punct:]]", "", words)), "\W+"))
return(words)
}
fuzzy_prep_words(A$name)
fuzzy_prep_words(B$name)
我可以从列表中提取单词,但无法计算其他列表中匹配的单词的数量和比例。
"X-ray right leg arteries" 在 B 中具有完全匹配,因此它应该 return 两列 - 匹配:“"X-ray right leg arteries" 和距离 = 100%。对于第二个短语 - "x-ray left shoulder",它应该 return 匹配 - "X-ray left leg arteries" 并且距离 66.67% 作为 "x-ray left shoulder" 中的 3 个词中的 2 个词匹配。对于第三个短语,它应该 return [=22= 中的任何一个], "X-ray right leg arteries".
我已经研究过 LV、COSINE、LCS 等字符串距离算法,所以我不想使用它,因为我的真实数据集中有大短语。
这样的怎么样?
m <- lapply(strsplit(tolower(gsub("[[:punct:]]", "", A$name)), " "), function(w1)
do.call(rbind.data.frame, lapply(strsplit(tolower(gsub("[[:punct:]]", "", B$name)), " "), function(w2) {
cbind.data.frame(
matches_string_from_B = paste(w2, collapse = " "),
percentage = sum(w1 %in% w2) / length(w1) * 100)
}
))
)
names(m) <- tolower(gsub("[[:punct:]]", "", A$name));
m;
$`xray right leg arteries`
matches_string_from_B percentage
1 xray left leg arteries 75
2 xray leg 50
3 xray right leg 75
4 xray right leg arteries 100
$`xray left shoulder`
matches_string_from_B percentage
1 xray left leg arteries 66.66667
2 xray leg 33.33333
3 xray right leg 33.33333
4 xray right leg arteries 33.33333
$`xray leg arteries`
matches_string_from_B percentage
1 xray left leg arteries 100.00000
2 xray leg 66.66667
3 xray right leg 66.66667
4 xray right leg arteries 100.00000
$`xray leg with 20km distance`
matches_string_from_B percentage
1 xray left leg arteries 40
2 xray leg 40
3 xray right leg 40
4 xray right leg arteries 40
解释:将A$name
的词条拆分成单词,计算B$name
的拆分词条匹配词的百分比,存入dataframes
的列表。使用 toupper
和 gsub("[[:punct:]]", "", ...)
使匹配不区分大小写并忽略标点符号。
更新
要获得最佳匹配(百分比),您可以执行以下操作:
do.call(rbind.data.frame, lapply(m, function(x) x[which.max(x$percentage), ]))
# matches_string_from_B percentage
#xray right leg arteries xray right leg arteries 100.00000
#xray left shoulder xray left leg arteries 66.66667
#xray leg arteries xray left leg arteries 100.00000
#xray leg with 20km distance xray left leg arteries 40.00000
我有两大短语列表。我需要检查其他列表中存在的单词的百分比,并从其他列表中获得最佳结果。
A <- data.frame(name = c(
"X-ray right leg arteries",
"x-ray left shoulder",
"x-ray leg arteries",
"x-ray leg with 20km distance"
), stringsAsFactors = F)
B <- data.frame(name = c(
"X-ray left leg arteries",
"X-ray leg",
"xray right leg",
"X-ray right leg arteries"
), stringsAsFactors = F)
fuzzy_prep_words <- function(words) {
words <- unlist(strsplit(tolower(gsub("[[:punct:]]", "", words)), "\W+"))
return(words)
}
fuzzy_prep_words(A$name)
fuzzy_prep_words(B$name)
我可以从列表中提取单词,但无法计算其他列表中匹配的单词的数量和比例。
"X-ray right leg arteries" 在 B 中具有完全匹配,因此它应该 return 两列 - 匹配:“"X-ray right leg arteries" 和距离 = 100%。对于第二个短语 - "x-ray left shoulder",它应该 return 匹配 - "X-ray left leg arteries" 并且距离 66.67% 作为 "x-ray left shoulder" 中的 3 个词中的 2 个词匹配。对于第三个短语,它应该 return [=22= 中的任何一个], "X-ray right leg arteries".
我已经研究过 LV、COSINE、LCS 等字符串距离算法,所以我不想使用它,因为我的真实数据集中有大短语。
这样的怎么样?
m <- lapply(strsplit(tolower(gsub("[[:punct:]]", "", A$name)), " "), function(w1)
do.call(rbind.data.frame, lapply(strsplit(tolower(gsub("[[:punct:]]", "", B$name)), " "), function(w2) {
cbind.data.frame(
matches_string_from_B = paste(w2, collapse = " "),
percentage = sum(w1 %in% w2) / length(w1) * 100)
}
))
)
names(m) <- tolower(gsub("[[:punct:]]", "", A$name));
m;
$`xray right leg arteries`
matches_string_from_B percentage
1 xray left leg arteries 75
2 xray leg 50
3 xray right leg 75
4 xray right leg arteries 100
$`xray left shoulder`
matches_string_from_B percentage
1 xray left leg arteries 66.66667
2 xray leg 33.33333
3 xray right leg 33.33333
4 xray right leg arteries 33.33333
$`xray leg arteries`
matches_string_from_B percentage
1 xray left leg arteries 100.00000
2 xray leg 66.66667
3 xray right leg 66.66667
4 xray right leg arteries 100.00000
$`xray leg with 20km distance`
matches_string_from_B percentage
1 xray left leg arteries 40
2 xray leg 40
3 xray right leg 40
4 xray right leg arteries 40
解释:将A$name
的词条拆分成单词,计算B$name
的拆分词条匹配词的百分比,存入dataframes
的列表。使用 toupper
和 gsub("[[:punct:]]", "", ...)
使匹配不区分大小写并忽略标点符号。
更新
要获得最佳匹配(百分比),您可以执行以下操作:
do.call(rbind.data.frame, lapply(m, function(x) x[which.max(x$percentage), ]))
# matches_string_from_B percentage
#xray right leg arteries xray right leg arteries 100.00000
#xray left shoulder xray left leg arteries 66.66667
#xray leg arteries xray left leg arteries 100.00000
#xray leg with 20km distance xray left leg arteries 40.00000