基于TF-IDF算法及余弦相似性的文本相似度检测

Posted by 3927 on 2021-11-24

前言

在之前的一篇文章中,我简单的向大家介绍了TF-IDF算法,用以评估一个词对于一个文件集或一个语料库中的其中一份文件的重要程度。对该算法还不太了解的同学可以查看该文章

TF-IDF算法经常用来提取一篇文章中的关键词,而关键词又经常可以作为我们判断两篇文章是否相似的依据。因此,我们可以将两篇文章间的关键词提取出来,之后采用余弦相似度计算两篇文章关键词之间的相似性,即可得出文章间的相似性。

余弦相似度


假设我们现在有两个向量a[x1,y1], b[x2,y2]。根据余弦定理,我们可以得知向量a,b之间夹角θ的余弦值为:
image.png

在坐标系中,可以将上面的公式转化成如下的形式:
image.png

根据上述公式,我们计算出的余弦值若越接近1,则说明θ角越接近0度,向量越相似。若余弦值越接近0,则说明θ角越接近90度,向量越不相似。

上述结论推广到n维仍然适用,在n维中,余弦值计算公式如下:

若其值越接近1,则说明向量越相似,越接近0,则说明向量越不相似。

文本相似度

上文中,我们得知了判断两个n维向量相似度的方法。根据前言,我们可以根据文本间关键词的相似程度来判断文本的相似程度。因此,我们可以将TF-IDF算法与余弦相似性算法结合起来,先将两篇文本的关键词转换为词频向量,之后计算词频向量间的余弦相似度,即可得出对应文章的相似度。

算法步骤

关键词->向量

  1. 首先,我们从两篇文章A与B中选取一定数量的关键词,我们这里假设选取5个,选取结果如下

    1
    2
    文章A: key_word1, key_word2, key_word3, key_word4, key_word5
    文章B: key_word2, key_word3, key_word5, key_word6, key_word7

    在这一步我们可以看到,两篇文章有一些关键词是重复的,比如key_word2 key_word3 key_word5

  2. 之后,我们将两篇文章的关键字合并成一个集合,如下:

    1
    key_word1, key_word2, key_word3, key_word4, key_word5, key_word6, key_word7
  3. 对集合中的每一个词,计算其分别在两篇文章中的TF-IDF值,得到如下列表:

TF-IDF值 文章A 文章B
key_word1 0.78 0.81
key_word2 0.23 0.51
key_word3 0.45 0.43
key_word4 0.67 0.70
key_word5 0.12 0.56
key_word6 0.27 0.28
key_word7 0.94 0.98
  1. 根据上表,我们即可得到两篇文章的关键词的词频向量(即为其TF-IDF值的集合),如下:
    1
    2
    文章A: A = [0.78, 0.23, 0.45, 0.67, 0.12, 0.27, 0.94]
    文章B: B = [0.81, 0.51, 0.43, 0.70, 0.56, 0.28, 0.98]

计算余弦相似性

在上一步,我们计算得出的两篇文章的关键词的词频向量AB。计算向量余弦值如下:

1
2
3
4
5
import numpy as np
a = np.array([0.78, 0.23, 0.45, 0.67, 0.12, 0.27, 0.94])
b = np.array([0.81, 0.51, 0.43, 0.70, 0.56, 0.28, 0.98])
a.dot(b)/(np.linalg.norm(a) * np.linalg.norm(b))
print(a) # 0.95485722106774

得出结果

根据上一步计算可得,文章A与文章B的关键词的词频向量的余弦相似度为0.95485722106774,接近1,则说明文章A与文章B高度相似

参考文章

# TF-IDF与余弦相似性的应用(二):找出相似文章