如何计算句子之间的结构相似度?


12

我正在研究一个需要确定两个句子是否相似的问题。我使用BM25算法和wordnet同义词集实现了一种解决方案,用于确定语法和语义相似性。该解决方案运行良好,即使句子中的单词顺序混乱,也可以衡量两个句子是相似的。例如

  1. Python是一门好语言。
  2. 语言是一个好的python。

我的问题是确定这两个句子是否相似。

  • 结构相似性的可能解决方案是什么?
  • 我将如何维持句子的结构?

您也许可以使用句子向量并进行比较。
艾登·格罗斯曼

我强烈建议您使用Gensim(radimrehurek.com/gensim)执行此任务。特别是模型LSI和/或word2vec和fasttext
Robin

Answers:


2

添加某种结构相似性度量的最简单方法是使用n-gram。在您的情况下,二元可能就足够了

浏览每个句子并收集成对的单词,例如:

  • “ python是”,“是一个”,“一个好的”,“好的语言”。

您的另一句话有

  • “语言a”,“好”,“好python”,“ python is”。

在八个二元组中,有两个相同(“ python is”和“ a good”),因此可以说结构相似度为2/8。

当然,如果您已经知道两个词在语义上相关,那么您也可以更加灵活。如果您想说Python是一种好语言,而在结构上与Java是好语言,则可以将其添加到比较中,以便有效地处理“ [PROG_LANG]是[POSITIVE-ADJ]语言”,或类似的东西。


5

首先,在开始之前,我建议您参考网络上的类似问题,例如/datascience/25053/best-practical-algorithm-for-sentence-likeityhttps:// stackoverflow。 com / questions / 62328 /是一种算法,可以说明两个词组的语义相似性

为了确定句子的相似性,我们需要考虑我们拥有什么样的数据。例如,如果您有一个标记的数据集,即相似的句子和相似的句子,那么直接的方法可能是使用监督算法对句子进行分类。

可以确定句子结构相似性的一种方法是平均由词嵌入算法(即word2vec)生成的词向量。这些算法为每个单词创建一个向量,它们之间的余弦相似度代表单词之间的语义相似度。(丹尼尔·L 2017)

使用单词向量,我们可以使用以下度量来确定单词的相似性。

  • 词的词嵌入之间的余弦距离
  • 词的词嵌入之间的欧式距离

余弦相似度是度量内部乘积空间的两个非零向量之间相似度的度量,该向量测量两个向量之间的夹角余弦。余弦角是句子之间根据内容的重叠程度的量度。

两个词向量之间的欧式距离提供了一种有效的方法,用于测量相应词的语言或语义相似性。(2015年4月D日)

或者,您可以计算句子的特征向量以确定句子的相似性。

特征向量是一组特殊的向量,它们与方程的线性系统(即矩阵方程)相关联。在这里,为每个聚类生成一个句子相似度矩阵,并计算该矩阵的特征向量。您可以在本文上阅读有关基于特征向量的句子排名方法的更多信息https://pdfs.semanticscholar.org/ca73/bbc99be157074d8aad17ca8535e2cd956815.pdf

对于源代码,Siraj Rawal有一个Python笔记本来创建一组词向量。然后可以使用单词向量来查找单词之间的相似性。源代码可在此处https://github.com/llSourcell/word_vectors_game_of_thrones-LIVE

另一个选择是来自Oreily的教程,该教程利用gensin Python库确定文档之间的相似性。本教程使用NLTK进行标记化,然后从语料库创建tf-idf(术语频率-反文档频率)模型。然后,将tf-idf用于确定文档的相似性。该教程位于https://www.oreilly.com/learning/how-do-i-compare-document-similarity-using-python


感谢您提供有关该问题的宝贵详细信息。我已经看过gensim的示例,但是我有一个问题,它可以解决我刚才提到的问题。尽管我创建的解决方案可以很好地找到句子之间的相似性,但是当单词顺序混乱时,它会卡住。
Shubham Tiwari

4

目前最佳的方法(2019):

现在,最有效的方法是使用Google的通用句子编码器paper_2018),该编码器使用句子嵌入的点积(即215个值的学习向量)来计算句子之间的语义相似度。相似度是介于0 (即无相似度)和1 (即强相似度)之间的浮点数

现在,该实现已集成到Tensorflow Hub中,可以轻松使用。这是一个现成的代码,用于计算2个句子之间的相似度。在这里,如您的示例所示,我将获得“ Python是一种好语言”“ Language a good python is”之间的相似之处。

代码示例:

#Requirements: Tensorflow>=1.7 tensorflow-hub numpy

import tensorflow as tf
import tensorflow_hub as hub
import numpy as np

module_url = "https://tfhub.dev/google/universal-sentence-encoder-large/3" 
embed = hub.Module(module_url)
sentences = ["Python is a good language","Language a good python is"]

similarity_input_placeholder = tf.placeholder(tf.string, shape=(None))
similarity_sentences_encodings = embed(similarity_input_placeholder)

with tf.Session() as session:
  session.run(tf.global_variables_initializer())
  session.run(tf.tables_initializer())
  sentences_embeddings = session.run(similarity_sentences_encodings, feed_dict={similarity_input_placeholder: sentences})
  similarity = np.inner(sentences_embeddings[0], sentences_embeddings[1])
  print("Similarity is %s" % similarity)

输出:

Similarity is 0.90007496 #Strong similarity

2019年的另一个选择是BERT句子嵌入-您可以在此处查看示例代码-github.com/hanxiao/bert-as-service
Adnan S
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.