文档相似度判断方法有很多种,比如说余弦相似度,ngram和著名的tf-idf方法去计算文本相似度。
本文以最简单比较好理解的余弦相似度,用python实操如何比较两段文字的相似度。
使用余弦相似度来计算不同文档之间的相似度。
假设有两个向量 b和a:
那么点积的定义是两个向量相加的每个分量的简单乘法。
两个向量之间的点积的结果不是另一个向量,而是一个值,即标量。
那这个例子为计算出0。它的背后含义是什么?我们再深入了解点积的几何定义是什么:
重新排列方程:
那么,这个术语
是向量a到向量b的投影,如下图所示:
当两个不同向量之间的点积为零时,它们彼此正交(角度为 90 度)。
这里使用的是 2D 示例,但其实,还可以计算更高维空间中向量之间的角度和相似性,这就是数学让我们看到的远不止显而易见的东西。
两个向量之间的余弦相似度是计算它们之间角度的余弦的度量。这个指标是方向的度量,而不是量级,它可以看作是归一化空间上文档之间的比较,除了文档的每个字数 (tf-idf) 的大小,这里余弦相似度考虑文档之间的角度。余弦相似度公式:
余弦相似度将生成一个指标,通过查看角度而不是大小来表示两个文档的相关性,如以下示例所示:
不同文档的余弦相似度值为 1(方向相同)、0(90 度)、-1(方向相反)。
即使有一个向量指向一个远离另一个向量的点,它们仍然可以有一个小角度,这是使用余弦相似性的中心点,测量往往会忽略文档上的较高项数。假设我们有一个单词“sky”出现 200 次的文档,另一个单词“sky”出现 50 次的文档,它们之间的欧几里得距离会更高,但角度仍然很小,因为它们指向同一个方向。所以考察word出现的次数对比较文档也很重要。
那么文档的向量空间模型(如下图所示),该模型被建模为向量(具有TF-IDF计数),并且还有一个公式来计算该空间中不同文档之间的相似性。
我们使用numpy来演示两段文档的余弦相似度
在此之前,我们需要对文字进行分词处理。
比如这里有三句话,那么我们会建立一个词典库包含这三句话出现的所有单词。
那么要建的词典库就是vocab= ['a', 'bar', 'black', 'foo', 'is', 'sentence', 'sheep', 'this']
这三句话对应的n维向量(这里n=8,就是词典库的个数)就是
其中如果该句子出现了某个word,那么计次数1,出现多次则计出现的次数。
对句子向量化之后,就可以计算每两个句子的相似度。
完整的程序如下:
import numpy as np
from math import sqrt, log
from itertools import chain, product
from collections import defaultdict
def cosine_sim(u,v):
return np.dot(u,v) / (sqrt(np.dot(u,u)) * sqrt(np.dot(v,v)))
def corpus2vectors(corpus):
def vectorize(sentence, vocab):
return [sentence.split().count(i) for i in vocab]
vectorized_corpus = []
vocab = sorted(set(chain(*[i.lower().split() for i in corpus])))
for i in corpus:
vectorized_corpus.append((i, vectorize(i, vocab)))
return vectorized_corpus, vocab
def create_test_corpus():
sent1 = "this is a foo bar"
sent2 = "foo bar bar black sheep"
sent3 = "this is a sentence"
all_sents = [sent1,sent2,sent3]
corpus, vocab = corpus2vectors(all_sents)
return corpus, vocab
def test_cosine():
corpus, vocab = create_test_corpus()
for sentx, senty in product(corpus, corpus):
print(sentx[0])
print(senty[0])
print("cosine =", cosine_sim(sentx[1], senty[1]))
#print
#print "Testing cosine..."
test_cosine()
输出结果如下:(0为不相关,1为一样,数字越大表示相似度越大):
例子1:
this is a foo bar
this is a foo bar
cosine = 0.9999999999999998
例子2:
this is a foo bar
foo bar bar black sheep
cosine = 0.5070925528371099
例子3:
this is a foo bar
this is a sentence
cosine = 0.6708203932499369
例子4:
foo bar bar black sheep
this is a foo bar
cosine = 0.5070925528371099
例子5:
foo bar bar black sheep
foo bar bar black sheep
cosine = 0.9999999999999999
例子6:
foo bar bar black sheep
this is a sentence
cosine = 0.0
例子7:
this is a sentence
this is a foo bar
cosine = 0.6708203932499369
例子8:
this is a sentence
foo bar bar black sheep
cosine = 0.0
例子9:
this is a sentence
this is a sentence
cosine = 1.0
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。