TF-IDF和余弦相似度的理解和应用

TF-IDF

什么是TF-IDF

TF-IDF(Term Frequency-Inverse Document Frequency)是信息检索和数据挖掘领域常用的加权技术,多用于文本的关键词挖掘,算法简单高效,也常用于文本数据的预处理。

TF-IDF由两个词组成,TF(Term Frequency)意思是词频 简言之就是统计词在文档中出现的频次,IDF(Inverse Document Frequency)意思是逆文档频次 ,它的大小与一个词的常见程度成反比(越少见的词的IDF越高,因为这些词是区别该文档和其他文档的关键词)。

案例理解

从一个实例理解TF和IDF的重要性。设想你正在阅读阿加莎的《ABC谋杀案》,准备用计算机提取该小说的关键词。

一个很容易想到的思路就是统计每个词出现的频率。如果某个词很重要,那么这次应该出现在小说多次。于是,我们对每个词进行”词频“统计。

结果很容易想到,我们对词频排序后,出现最多词肯定是“的”、“是”,“在”这样的词,这样词称为“停用词”,在一般自然语言的预处理过程都需要去除停用词。

那么我们在去除掉停用词后,可能发现“安多弗”、“波洛”、“信”出现次数差不多,但这不能表示这几个词的重要性是一样的。

因为“信”是很常见的词,相对而言“安多弗”和“波洛”出现在特定的小说中,因此这两个词的排名应该在“信”之上。这就需要用到IDF来计算每个词的逆文档频率。

知道TF和IDF后,TF-IDF计算非常简单,就是TF和IDF相乘的结果。某个词在文章中的TF-IDF值越大,那么这次在文档中的重要性越高,所以通过计算文档中各个词的TF-IDF值并排序,可以知道该文档的关键词。

算法公式

第一步,计算词频(TF)

词频=某个词在文档中的出现次数词频=某个词在文档中的出现次数

考虑到不同的文档有长短之分,在对多文档进行分析需要进行标准化。

词频=某个词在文章中出现的次数文章总数词频=\frac{某个词在文章中出现的次数}{文章总数}

或者

词频=某个词在文章中出现的次数该文出现最多的词的出现次数词频=\frac{某个词在文章中出现的次数}{该文出现最多的词的出现次数}

第二步,计算逆文档频率
引入语料库(corpus)的概念,即语料库包含了多段文章、语料,用来模拟语言的使用环境。

逆文档频率(IDF)=log(语料库的文档总数包含该词的文档数+1)逆文档频率(IDF)=log(\frac{语料库的文档总数}{包含该词的文档数+1})

可见,如果一个词出现在多个文档中,逆文档频率就越接近0,+1的目的是为了避免分母为0(即所有文档都不包含该词)的情况出现。

第三步,计算TF-IDF
TFIDF=词频(TF)×逆文档频率(IDF)TF-IDF=词频(TF)\times 逆文档频率(IDF)

可以看到TF-IDF的值与该词在该文档中出现的次数呈正比,与该词在整个语料库中出现的频率呈反比。

案例计算

仍以《ABC谋杀案》为例,假设该小说的总长度为100000,“安多弗”,“波洛”,“信”的出现次数均为100次,则这三个词的词频(TF)均为0.001。通过google搜索发现包含“的”的网页数有126亿。包含“安多弗”的网页有0.0009亿,包含“波洛”的网页有2亿,包含“信”的网页有8亿。则他们的TF-IDF计算如下:

TF 包含该词的文档数(亿) IDF TF-IDF
安多弗 0.001 0.0009 11.85 0.01185
波洛 0.001 2 4.14 0.00414
0.001 8 2.76 0.00276

从上表可以看出,安多弗的TF-IDF值最高,因此该小说的关键词可以有安多弗,这也是第一次命案发生的地方,ABC的A。

总结

除了自动提取关键词,TF-IDF算法还可以用于许多别的地方。比如,信息检索时,对于每个文档,都可以分别计算一组搜索词的TF-IDF,将它们相加,就可以得到整个文档的TF-IDF。这个值最高的文档就是与搜索词最相关的文档。

TF-IDF算法的优点是简单快速,结果比较符合实际情况。缺点是,单纯以"词频"衡量一个词的重要性,不够全面,有时重要的词可能出现次数并不多。而且,这种算法无法体现词的位置信息,出现位置靠前的词与出现位置靠后的词,都被视为重要性相同,这是不正确的。(一种解决方法是,对全文的第一段和每一段的第一句话,给予较大的权重。)

余弦相似度

我们有时候在浏览一篇文章时,推荐系统会给我们推荐一些相似文章,那么在前深度学习时代,查找相似文章的任务是如何完成的呢?
这就要提到一个很重要的概念,余弦相似度,在很多深度学习算法中,也大量使用余弦相似度来度量两个向量或者embedding的相似度。与其他度量两个向量相似度的方法(欧式距离、点积)等,余弦相似度主要考虑两个向量在向量空间的夹角,或者说是两者的方向。

案例引入

举一个简单的例子:

句子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]

当然,这里也可以计算每个词的TF-IDF值作为句子的向量。

对两个向量的相似度进行度量
我们可以通过判断两个向量aabb的夹角,如果夹角越小则越相近,对于二维空间中两个向量来说,我们可以用余弦定理来计算他们的夹角。
cosθ=a2+b2c22ab(1)cos\theta = \frac{a^2+b^2-c^2}{2ab} \tag{1}

如果a=[x1,y1],b=[x2,y2]a=[x_1,y_1],b=[x_2,y_2],可以将(1)(1)式改为:
cosθ=x1x2+y1y2x12+y12×x22+y22(2)cos\theta = \frac{x_1x_2+y_1y_2}{\sqrt{x_1^2+y_1^2}\times \sqrt{x_2^2+y_2^2}} \tag{2}

扩展到n为向量,不难发现,计算余弦值就是两向量点积的结果除以二者长度之积。因此,计算余弦相似度的公式为:
cosθ=ABA×B(3)cos\theta = \frac{A\cdot B}{|A|\times|B|} \tag{3}

我们可以得到句子A和B的余弦值
cosθ=1312×16=0.938cos\theta = \frac{13}{\sqrt{12} \times \sqrt{16}}\\ =0.938

余弦值越接近1,就说明两向量的夹角越接近0,两者越相似。

匹配相似文章的算法

  1. 使用TF-IDF算法,找出两篇文章的关键词;
  2. 每篇文章各取出若干个关键词(比如20个),合并成一个集合,计算每篇文章对于这个集合中的词的词频(为了避免文章长度的差异,可以使用相对词频);
  3. 生成两篇文章各自的词频向量;
  4. 计算两个向量的余弦相似度,值越大就表示越相似。

参考

TF-IDF与余弦相似性的应用(一):自动提取关键词
Tf-Idf详解及应用
机器学习:生动理解TF-IDF算法