我想在一个栏目的基础上找到另一个栏目的信息。因此,我在一个专栏中有一些单词,在另一个专栏中有完整的句子。我想知道它是否找到了这些句子中的单词。但是有时候单词不一样,所以我不能使用SQL like函数。因此,我认为模糊匹配+某种“喜欢”函数会很有帮助,因为数据看起来像这样:
Names Sentences
Airplanes Sarl Airplanes-Sàrl is part of Airplanes-Group Sarl.
Kidco Ltd. 100% ownership of Kidco.Ltd. is the mother company.
Popsi Co. Cola Inc. is 50% share of PopsiCo which is part of LaLo.这些数据大约有2000行,需要一个逻辑来判断Airplanes Sarl是否真的在句子中,它也适用于Kidco Ltd.,它在句子中被称为“Kidco.Ltd”。
为了简化问题,我不需要它搜索列中的所有句子,它只需要查找单词Kidco Ltd.并在数据帧的同一行中搜索它。
我已经用df.apply(lambda s: fuzz.ratio(s‘’Names‘,s’‘Sentences’),axis=1)在Python中尝试过了。
但是我得到了很多unicode /ascii错误,所以我放弃了,并想在R中尝试一下。有什么建议可以在R中进行吗?我在Stackoverflow上看到的答案会模糊地匹配专栏中的所有句子,这与我想要的不同。有什么建议吗?
发布于 2017-05-29 23:03:21
也许可以尝试标记化+语音匹配:
library(RecordLinkage)
library(quanteda)
df <- read.table(header=T, sep=";", text="
Names ;Sentences
Airplanes Sarl ;Airplanes-Sàrl is part of Airplanes-Group Sarl.
Kidco Ltd. ;Airplanes-Sàrl is part of Airplanes-Group Sarl.
Kidco Ltd. ;100% ownership of Kidco.Ltd. is the mother company.
Popsi Co. ;Cola Inc. is 50% share of PopsiCo which is part of LaLo.
Popsi Co. ;Cola Inc. is 50% share of Popsi Co which is part of LaLo.")
f <- soundex
tokens <- tokenize(as.character(df$Sentences), ngrams = 1:2) # 2-grams to catch "Popsi Co"
tokens <- lapply(tokens, f)
mapply(is.element, soundex(df$Names), tokens)
# A614 K324 K324 P122 P122
# TRUE FALSE TRUE TRUE TRUE 发布于 2017-05-29 23:52:28
这是一个使用我在评论中建议的方法的解决方案,在这个例子中它工作得很好:
library("stringdist")
df <- as.data.frame(matrix(c("Airplanes Sarl","Airplanes-Sàrl is part of Airplanes-Group Sarl.",
"Kidco Ltd.","100% ownership of Kidco.Ltd. is the mother company.",
"Popsi Co.","Cola Inc. is 50% share of PopsiCo which is part of LaLo.",
"some company","It is a truth universally acknowledged...",
"Hello world",list(NULL)),
ncol=2,byrow=TRUE,dimnames=list(NULL,c("Names","Sentences"))),stringsAsFactors=FALSE)
null_elements <- which(sapply(df$Sentences,is.null))
df$Sentences[null_elements] <- "" # replacing NULLs to avoid errors
df$dist <- mapply(stringdist,df$Names,df$Sentences)
df$n2 <- nchar(df$Sentences)
df$n1 <- nchar(df$Names)
df$match_quality <- df$dist-(df$n2-df$n1)
cutoff <- 2
df$match <- df$match_quality <= cutoff
df$Sentences[null_elements] <- list(NULL) # setting null elements back to initial value
df$match[null_elements] <- NA # optional, set to FALSE otherwise, as it will prevent some false positives if Names is shorter than cutoff
# Names Sentences dist n2 n1 match_quality match
# 1 Airplanes Sarl Airplanes-Sàrl is part of Airplanes-Group Sarl. 33 47 14 0 TRUE
# 2 Kidco Ltd. 100% ownership of Kidco.Ltd. is the mother company. 42 51 10 1 TRUE
# 3 Popsi Co. Cola Inc. is 50% share of PopsiCo which is part of LaLo. 48 56 9 1 TRUE
# 4 some company It is a truth universally acknowledged... 36 41 12 7 FALSE
# 5 Hello world NULL 11 0 11 22 NAhttps://stackoverflow.com/questions/44244948
复制相似问题