快捷搜索:  汽车  科技

文本相似度判断:文本相似度量概述

文本相似度判断:文本相似度量概述对于上述两个句子,我们得到5 /(5 3 2)= 0.5的 Jaccard相似度,它是该集合的交集的大小除以集合的总大小。 Venn关于Jaccard相似性的两个句子的图表句子1: AI is our friend and it has been friendly句子2: AI and humans have always been friendly为了使用Jaccard similarity计算相似度,我们将首先执行lemmatization 以将单词缩减为相同的词根。在我们的例子中,“friend”和“friendly”都将成为“friend”,“has”和“have”都将成为“has”。绘制这两个句子的维恩图我们得到:

在为搜索引擎开发自然语言模型时,我经常会问“这两个词有多相似?”,“这两个句子有多相似?”,“这两个文档有多相似?”。在本文中,我们将更深入地探讨句子或文档相似性的技巧。

文本相似度判断:文本相似度量概述(1)

我们如何理解我们周围的所有文字?

有几个文本相似度量度,但我们会看看最常见的Jaccard相似度和余弦相似度。

Jaccard Similarity:

Jaccard相似或交叉的交集被定义为交集的大小除以两个集合的大小。让我们以两个句子为例:

句子1: AI is our friend and it has been friendly

句子2: AI and humans have always been friendly

为了使用Jaccard similarity计算相似度,我们将首先执行lemmatization 以将单词缩减为相同的词根。在我们的例子中,“friend”和“friendly”都将成为“friend”,“has”和“have”都将成为“has”。绘制这两个句子的维恩图我们得到:

Venn关于Jaccard相似性的两个句子的图表

对于上述两个句子,我们得到5 /(5 3 2)= 0.5的 Jaccard相似度,它是该集合的交集的大小除以集合的总大小。

Python中Jaccard similarity的代码是:

def get_jaccard_sim(str1 str2):

a = set(str1.split())

b = set(str2.split())

c = a.intersection(b)

return float(len(c)) / (len(a) len(b) - len(c))

有一点需要注意的是,由于我们使用集合,“friend ”在第1句中出现了两次,但它不影响我们的计算 - 这将随着余弦相似度而改变。

余弦相似度:

余弦相似度通过测量两个向量之间角度的余弦来计算相似度。这被计算为:

文本相似度判断:文本相似度量概述(2)

两个向量A和B的余弦相似度计算

使用余弦相似度,我们需要将句子转换为矢量。一种方法是使用tf(词频)或TF-IDF(词频 - 逆文档频率)的词组。TF或TF-IDF的选择取决于应用,并且对余弦相似性如何实际执行是不重要的 - 这只需要向量。TF一般而言对于文本相似性很好,但TF-IDF对于搜索查询相关性很好。

另一种方法是使用Word2Vec或我们自己的自定义word embeddings将单词转换为矢量。

tf / tf-idf与bag of words和word embeddings之间有两个主要区别:

  • tf / tf-idf每个单词创建一个数字,word embeddings通常会为每个单词创建一个向量。

  • tf / tf-idf对整个分类文档很有好处,但word embeddings对于识别上下文内容很有帮助。

我们来计算这两个句子的余弦相似度:

句子1:AI is our friend and it has been friendly

句子2:AI and humans have always been friendly

步骤1,我们将使用bag of words来计算术语频率:

文本相似度判断:文本相似度量概述(3)

在两个句子的词形化之后的术语频率

步骤2,上面显示的期限频率计数的主要问题是它支持较长的文档或句子。解决这个问题的一种方法是用各自的量值或L2标准对术语频率进行归一化。总结每个频率的平方并取平方根,句子1的L2范数为3.3166,句子2为2.6458。用这些规范划分词频以上,我们得到:

文本相似度判断:文本相似度量概述(4)

使用L2标准规范术语频率

步骤3,因为我们已经将两个向量归一化为长度为1,所以我们可以用点积来计算余弦相似度:

余弦相似度=(0.302 * 0.378) (0.603 * 0.378) (0.302 * 0.378) (0.302 * 0.378) (0.302 * 0.378)= 0.684

因此,这两个句子的余弦相似度为0.684,这与完全相同的两个句子的Jaccard相似度是不同的,这两个句子是0.5(上面计算的)

Python中的余弦相似性代码是:

import math

from collections import Counter

def get_cosine_sim(str1 str2):

tf1 = Counter(str1.split()) # Term Frequency

tf2 = Counter(str2.split())

norm1 = math.sqrt(sum([x**2 for x in tf1.values()])) # L2 norm

norm2 = math.sqrt(sum([x**2 for x in tf2.values()]))

vec1 = [float(x)/norm1 for x in tf1.values()] # Vector 1

vec2 = [float(x)/norm2 for x in tf2.values()] # Vector 2

return sum(x*y for x y in zip(vec1 vec2)) # Dot Product

Jaccard相似度与余弦相似度的区别:
  • Jaccard相似度仅为每个句子/文档采用唯一的单词集,而余弦相似度则采用向量的总长度。(这些载体可以从词语词频或tf-idf)

  • 这意味着如果在句子1中多次重复单词“朋友”,余弦相似性会改变,但是Jaccard相似性不会改变。例如,如果在第一个句子中重复50次“朋友”一词,则余弦相似度下降到0.4,但Jaccard相似度保持在0.5。

  • Jaccard相似性适用于重复不重要的情况,余弦相似性适用于分析文本相似性时重复重要的情况。对于两个产品说明,使用Jaccard相似性会更好,因为单词的重复不会降低它们的相似性。

猜您喜欢: