【问题标题】:Select similar sentences选择相似的句子
【发布时间】:2021-05-23 05:57:01
【问题描述】:

如果我有一组句子,我想提取重复的句子,我应该像下面的例子一样工作:

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",
         "Today is my One Hundred and Eleventh birthday",
         "I'm sorry I brought this upon you, 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",
             "Today is my One Hundred and Eleventh birthday",
             "I'm sorry I brrrought this upon, my",
             "So there I was at mercy of three monstrous troll",
             "Today is One Hundred Eleventh birthday",
             "I'm sorry I brought this upon you, 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

RecordLinkage 包中的 levenshteinSim 函数可以帮助我:

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 的值。我可以写一个 double for loop 并选择,例如,那些 Levenshtein 编辑距离大于 0.7 的句子对(例如)。但是,没有更简单的方法吗?

【问题讨论】:

    标签: r string-comparison edit-distance


    【解决方案1】:

    您可以使用基于广义 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
    

    要在cutree 中为h=eight 找到合适的值,我们可以绘制树状图。

    plot(hc)
    abline(h=10, col=2, lty=2)
    

    【讨论】:

      【解决方案2】:

      TLDR:您可能可以使用词袋 (BoW) 表示并将这些句子转换为向量。然后,只需检查相关性,如果它们与另一个的相关性太高,则消除它们。

      词袋
      让我们想想下面这句话:

      • 杰克是个英俊帅气的男人

      并假设我们的整个单词世界都在那个句子中。然后,我们可以简单地为这个句子中出现的单词数(每个单词 1 个)创建一个向量,它是一个具有5 特征的向量(Jack, is, a, nice, man)。

      那么,对应的 BoW 表示为:[1, 1, 1, 2, 1]
      这个宇宙中的另一个句子可能是,

      • 杰克杰克帅哥

      同样,我们可以使用 5 特征向量来表示这句话。

      [2, 0, 0, 2, 1].

      然后,你可以在R中计算这句话的相似度。

      # Jack is a handsome, handsome man
      first <- c(1,1,1,2,1)
      
      # Jack Jack handsome handsome man
      second <- c(2,0,0,2,1)
      
      cor(first, second, method = "pearson")
      #> [1] 0.559017
      

      【讨论】:

        【解决方案3】:

        您可以为每个句子生成嵌入,然后计算它们之间的余弦相似度。

        可以使用基于 BERT 的模型或 GLOVE 模型生成嵌入。

        BERT:Sentence transformer 以及非常具体的语义相似性或释义挖掘。

        手套:标记句子,清理停用词,使用引理获取基本词,生成词嵌入并将它们合并为一个嵌入,然后计算相似度得分,即相同的余弦距离。

        相似度得分 > 93 - 95% 将为您提供最相似句子的所有列表。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-01-10
          • 2020-12-27
          • 2015-07-04
          • 1970-01-01
          • 1970-01-01
          • 2021-11-21
          相关资源
          最近更新 更多