如何比较段落之间的相似性 NLP

Posted

技术标签:

【中文标题】如何比较段落之间的相似性 NLP【英文标题】:How to compare similarities between paragraphs NLP 【发布时间】:2021-10-13 16:03:03 【问题描述】:

我一直在尝试 NLP,并使用 Doc2Vec 模型。

我的目标是一个论坛建议的问题功能。例如,如果用户键入一个问题,它会将向量与其他已经提出的问题进行比较。到目前为止,在将一个问题与另一个提出的问题进行比较的意义上,这一切正常。

但是,我想将此扩展到比较问题的主体。例如,就像 *** 一样,我正在为我的问题写一个描述。

我了解 doc2vec 通过段落 id 表示句子。因此,对于我首先谈到的问题示例,每个句子都是一个唯一的段落 ID。但是,对于段落,即问题的主体,句子将与同一段落中的其他句子具有相同的 id。

para = 'This is a sentence. This is another sentence'
[['This','is','a','sentence',tag=[1]], ['This','is','another','sentence',tag=[1]]

我想知道如何去做。我怎样才能输入这样的语料库:

['It is a nice day today. I wish I was outside in the sun. But I need to work.']

并将其与另一个段落进行比较,如下所示:

['It is a lovely day today. The sun is shining outside today. However, I am working.']

我希望两者之间非常相似。相似度是通过句子到句子而不是段落到段落来计算的吗?即

cosine_sim(['It is a nice day today'],['It is a lovely day today.]

然后对其他句子执行此操作并平均相似度分数?

谢谢。

编辑 我很困惑的是使用上面的句子,说向量是这样的

sent1 = [0.23,0.1,0.33...n]
sent2 = [0.78,0.2,-0.6...n]
sent3 = [0.55,-0.5,0.9...n]

#Avergae out these vectors

para = [0.5,0.2,0.3...n]

并使用此向量与使用相同过程的另一个段落进行比较。

【问题讨论】:

如果超出您的需求范围,请原谅我,但 SpaCy 非常适合进行相似性匹配。 NLP 实验的必备品看看spacy.io/usage/linguistic-features 【参考方案1】:

我假设您说的是 Python Gensim 库中的 Doc2Vec 模型 - 基于类似 word2vec 的“段落向量”算法。 (有许多替代方法可以将文本转换为向量,有时还有其他方法,包括将词向量平均在一起的非常简单的方法,也称为“Doc2Vec”。)

Doc2Vec 没有句子或段落的内部概念。它只考虑文本:单词标记列表。因此,您决定提供多大的文本块,并与 tag 键关联:多词片段、句子、段落、部分、章节、文章、书籍等等。

您在初始批量训练期间提供的每个 tag 都会根据您在其旁边提供的单词列表进行训练,并存储在模型中。因此,您可以通过以下方式从训练中检索这些向量:

d2v_model.dv[tag]

您还可以使用经过训练的冻结模型来推断新词列表的新向量:

d2v_model.infer_vector(list_of_words)

(注意:这些词应该与训练期间的词一样进行预处理/标记,并且模型在训练中不知道的任何词都将被忽略。)

而且,一旦你有了两个不同文本的向量,无论用什么方法,你都可以通过余弦相似度来比较它们。

为了创建您的文档向量,您可能希望将questionbody 一起运行到一个文本中。 (如果question 更重要,你甚至可以考虑对重复question 不止一次的伪文本进行训练,例如在body 之前和之后。)或者你可能想分别对待它们,所以某些下游进程可以对question->question 相似性的权重不同于body->bodyquestion->body。什么最适合您的数据和目标通常必须通过实验来确定。

【讨论】:

感谢您的回复,但我对如何“比较2段”有点迷茫。我知道如何比较 2 个句子,但从我读过的内容来看,Doc2Vec 需要一个标签来表示句子来自的段落。但是,没有实现如何将 2 个段落一起比较。 因此,我建议将句子向量平均化吗?我会更新我的问题以更好地反映我的意思 Doc2Vec 中的“句子”和“段落”没有区别。它们都只是单词列表。如果您知道如何比较两个句子,只需对段落的所有单词而不是句子的所有单词做完全相同的事情。 (在与Doc2Vec 合作时,我建议从您的思维中消除“句子”和“段落”这两个词。相反,考虑一下单词列表,如果有帮助,您可以将其称为“文本”或“文档”。) 谢谢,所以基本上我的误解是,对于 Doc2Vec,您将一个单词列表输入到模型中(通常是一个句子),但是您可以将多个句子组合成一个单词列表并输入型号? 例如 ['It is sunny today. I should go outside then. What a day!'] - 在嵌入的句子中,这将是 3 个标记化列表。是否可以删除标点符号(即句号等)并用所有标记化的单词表示 1 个列表并将其输入 doc2vec?

以上是关于如何比较段落之间的相似性 NLP的主要内容,如果未能解决你的问题,请参考以下文章

NLP 中文形近字相似度算法开源实现

NLP文本相似度(TF-IDF)

如何在 Python 中比较两个字符串(英语除外)之间的相似性

NLP 系列之一:用 Trigram 进行 Article Spinner

您如何比较两个树状图(在 R 中)之间的“相似性”?

如何计算两个文本文档之间的相似度?