目录
一、基本算法--余弦相似度
1、使用TF-IDF算法,找出两篇文章的关键词;
2、每篇文章各取出若干个关键词(比如20个),合并成一个集合,计算每篇文章对于这个集合中的词的词频TF(为了避免文章长度的差异,可以使用相对词频);
3、生成两篇文章各自的词频向量;
4、计算两个向量的余弦相似度,值越大就表示越相似。
假设向量a、b的坐标分别为(x1,y1)、(x2,y2) 。则:
设向量 A = (A1,A2,...,An),B = (B1,B2,...,Bn) 。推广到多维,数学家已经帮我们证明了,所以你只要记住下面的公式:
简单来说可以写成下面的式子:
举一个具体例子,我们先从句子开始:
句子A:我喜欢看电视,不喜欢看电影。
句子B:我不喜欢看电视,也不喜欢看电影。
第一步:分词
句子A:我/喜欢/看/电视,不/喜欢/看/电影。
句子B:我/不/喜欢/看/电视,也/不/喜欢/看/电影。
第二步:列出所有的词
我,喜欢,看,电视,电影,不,也
第三步:计算词频
句子A:我 1,喜欢 2,看 2,电视 1,电影 1,不 1,也 0
句子B:我 1,喜欢 2,看 2,电视 1,电影 1,不 2,也 1
第四步:写出词频向量
句子A:[1, 2, 2, 1, 1, 1, 0]
句子B:[1, 2, 2, 1, 1, 2, 1]
第五步:计算余弦值
余弦值越接近1,就表明夹角越接近0度,也就是两个向量越相似,这就叫"余弦相似性"。
简单来说上面计算出的值代表两个句子大概九成相似,越接近1就越相似。
二、计算余弦相似度
余弦相似度(值越大,两者越相似,向量夹角越小,极限是重合,夹角为0,此时余弦相似度是1)。
2.1、python实现
自己实现一个,按照cos的计算公式——向量的内积除以向量模长的积代码如下:
def python_cos(q_vec, b_vec):
"""
计算余弦相似度
:param q_vec: 一维数组
:param b_vec: 一维数组
:return:
"""
dot_q_b = 0
q_vec_length = 0
b_vec_length = 0
for q, b in zip(q_vec, b_vec):
dot_q_b += q * b
q_vec_length += q * q
b_vec_length += b * b
length = (q_vec_length ** (1 / 2)) * (b_vec_length ** (1 / 2))
cos_sim = dot_q_b / length # 向量的内积除以向量模长的积
return cos_sim
a = [1, 2, 2, 1, 1, 1, 0]
b = [1, 2, 2, 1, 1, 2, 1]
print(python_cos(a, b)) # cos_sim 0.9381941874331419。
2.2、sklearn
sklearn机器学习算法常用库,这个就比较简单了只需要直接调用sklearn中相关的API即可:
pip3 install -U scikit-learn
from sklearn.metrics.pairwise import cosine_similarity
def cos(a, b):
"""
a和b都要是2维
"""
cos = cosine_similarity(a,b)
return cos
a = [[1,2,3],[3,2,1], [3,4,5]]
b = [[3,2,1],[1,2,3]]
print(cos(a, b))
'''结果 a中的每一项与b中每一项的相似度
[[0.71428571 1. ]
[1. 0.71428571]
[0.83152184 0.98270763]]
'''
注意这里的参数,a和b都必须是二维的,不然会报错;a和b中的元素个数不定。
2.3、scipy ---最快
import scipy.spatial
@coast_time
def cos(a, b):
'''
a和b都要是2维,a和b中的元素个数不定
'''
dis = scipy.spatial.distance.cdist(a,b,'cosine')
cos = 1 - dis[0]
return cos
a = [[1,2,3]]
b = [[3,2,1],[4,5,6], [2,2,3]]
print(cos(a, b))
'''结果
func cos coast time:0.00006230 s
[0.71428571 0.97463185 0.97230559]
'''
注意这里的参数,a和b的数据类型可以是数组、np.array();a和b都必须是二维的;a和b中的元素个数不定。这里dis可以理解为余弦距离,要用1-dis才是余弦相似度。
2.4、pytorch
sklearn机器学习算法常用库,这个就比较简单了只需要直接调用sklearn中相关的API即可:
PyTorch windows安装torch: pip3 install torch torchvision torchaudio
import torch
torch.set_default_tensor_type(torch.FloatTensor)
@coast_time
def torch_cos_new(a, b):
"""
a,b必须是tensor张量;torch_cos中有个bug,a和b的第一维只能是1,不然会出现错误结果
"""
cos = torch.cosine_similarity(a, b, dim=1)
return cos
a = torch.tensor([[1,2,3]]).float() # 转化为tensor张量
b = torch.tensor([[3,2,1],[4,5,6], [2,2,3]]).float()
print(torch_cos_new(a, b))
'''结果
tensor([0.7143, 0.9746, 0.9723])
func torch_cos_new coast time:0.00072610 s
'''
三、参考
https://www.haitaoseo.com/950191.html 文章相似度检测工具(一种简单高效的算法)
https://github.com/zhao-dapeng/Cosine zhao-dapeng/Cosine
余弦相似度计算方法与Python实现
1万+

被折叠的 条评论
为什么被折叠?



