问题描述
如果我有一组句子并且我想提取重复项,我应该像下面的例子一样工作:
sentences<-c("So there I was at the mercy of three monstrous trolls","Today is my One Hundred and Eleventh birthday","I'm sorry I brought this upon you,my","So there I was at the mercy of three monstrous trolls",my")
sentences[duplicated(sentences)]
返回:
[1] "So there I was at the mercy of three monstrous trolls"
[2] "Today is my One Hundred and Eleventh birthday"
[3] "I'm sorry I brought this upon you,my"
但就我而言,我的句子彼此相似(例如,由于拼写错误),我想选择彼此更相似的句子。例如:
sentences<-c("So there I was at the mercy of three monstrous trolls","I'm sorry I brrrought this upon,"So there I was at mercy of three monstrous troll","Today is One Hundred Eleventh birthday",my")
根据这个例子,我想在以下每一对中选择一个:
I'm sorry I brought this upon you,my
I'm sorry I brrrought this upon,my
Today is One Hundred Eleventh birthday
Today is my One Hundred and Eleventh birthday
So there I was at the mercy of three monstrous trolls
So there I was at mercy of three monstrous troll
levenshteinSim
包中的 RecordLinkage
函数可以帮助我:
library(RecordLinkage)
levenshteinSim(sentences[1],sentences[2])
levenshteinSim(sentences[1],sentences[3])
levenshteinSim(sentences[1],sentences[4])
levenshteinSim(sentences[1],sentences[5])
levenshteinSim(sentences[1],sentences[6])
levenshteinSim(sentences[2],sentences[3])
levenshteinSim(sentences[2],sentences[4])
levenshteinSim(sentences[2],sentences[5])
levenshteinSim(sentences[2],sentences[6])
依此类推,为最相似的句子返回接近 1 的值。我可以写一个双 for loop
并选择,例如,那些 Levenshtein 编辑距离大于 0.7 的句子对(例如)。但是,难道没有更简单的方法来做到这一点吗?
解决方法
您可以使用基于广义 Levenstein 距离的 adist
计算近似字符串距离矩阵,然后使用 hclust
进行层次聚类。
ld <- adist(tolower(sentences))
hc <- hclust(as.dist(ld))
data.frame(x=sentences,cl=cutree(hc,h=10))
# x cl
# 1 So there I was at the mercy of three monstrous trolls 1
# 2 Today is my One Hundred and Eleventh birthday 2
# 3 I'm sorry I brrrought this upon,my 3
# 4 So there I was at mercy of three monstrous troll 1
# 5 Today is One Hundred Eleventh birthday 2
# 6 I'm sorry I brought this upon you,my 3
要为 h=
中的 cutree
8 找到合适的值,我们可以绘制树状图。
plot(hc)
abline(h=10,col=2,lty=2)
,
TLDR:可能您可以使用词袋 (BoW) 表示并将这些句子转换为向量。然后,只需检查相关性,如果相关性与另一个相关性太高,则将其消除。
词袋
让我们想想下面这句话:
- 杰克是一个英俊帅气的男人
并假设我们的整个单词世界都在那个句子中。然后,我们可以简单地为这个句子中出现的单词数量创建一个向量(每个单词 1 个),这是一个具有 5
特征的向量(Jack,is,a,nice,man)。
那么,对应的BoW表示为:[1,1,2,1]
.
这个宇宙中的另一个句子可能是,
- 杰克杰克帅哥
同样,我们可以使用我们的 5
特征向量来表示这句话。
[2,1]
。
然后,您可以在 R 中计算这些句子的相似度。
# Jack is a handsome,handsome man
first <- c(1,1)
# Jack Jack handsome handsome man
second <- c(2,1)
cor(first,second,method = "pearson")
#> [1] 0.559017
,
您可以为每个句子生成嵌入,然后计算它们之间的余弦相似度。
可以使用基于 BERT 的模型或 GLOVE 模型生成嵌入。
BERT:Sentence transformer & 是非常具体的语义相似性或释义挖掘。
GLOVE:对句子进行分词,清理停用词,使用引理获取基本词,生成词嵌入并将它们合并为一个嵌入,然后计算相似度得分,即相同的余弦距离。
相似度得分 > 93 - 95% 将为您提供最相似句子的所有列表。