1. 问题描述
给你若干篇文档,找出这些文档中最相似的两篇文档?
相似性,可以用距离来衡量。而在数学上,可使用余弦来计算两个向量的距离。
\[cos(\vec a, \vec b)=\frac {\vec a*\vec b}{||\vec a||*||\vec b||}\]
因此,用向量来表示文档,然后就可以用余弦来计算两篇文章之间的相似度了。
2. 词袋模型
一篇文档里面有很多很多句子,每个句子又是由一个个的词组成。词袋模型,通俗地讲,就是:把一篇文档看成词袋,里面装着一个个的词。
从而,将一篇文档转化成了一个个的词(或者称之为 term),显然地,文档转化成一个个的词之后,词与词之间的顺序关系丢失了。
3. TF-IDF
在计算文档之间相似度之前,会有一些前提条件:
- 我们有一个文档集合C,文档集合C里面一共有N篇文档
- 我们有一个词典D,或者叫词库(Vocabulary),词库里面一共有M个词
3.1 文档到向量的转化
向量是有长度的,向量中的每个元素是数值,比如一个三维实值向量:(1.2,2.8,4.5)
首先将文档通过词袋模型转化成一个个的词,一般地,由于文档中的词都会存在于词典D中,定义一个M维向量(M等于词典大小),若文档中的某个词在词典中出现了,就给这个词赋一个实数值。若未出现,则在相应位置处赋值为0
3.2 使用TF-IDFT 衡量每个词(term)的权重
在给定的文档集合C和词典D的情况下,如何来衡量一个词(term)的权重呢?即如何计算这个实数值呢?
3.2.1 tf值
tf(term frequency),是指 term 在某篇文档中出现的频率。假设文档集合中共有10篇文章,词:‘‘国家‘‘,在文档1中出现了6次,那么对于文档1而言,‘国家‘这个词的tf值为6
3.2.2 idf值
‘国家‘这个词在文档1中的idf值 由 词(term) 出现在各个文档中数目来决定,比如‘国家‘一共在8篇文档中出现了,那么对于文档1而言,‘国家‘这个词的idf值由如下公式计算:
\[idf_t=log\frac{N}{df_t}\]
其中,N=10 表示文档集合中共有10篇文章。df_t=8,表示 term 国家 在8篇文档中出现了。
而TF-IDF,就是将tf值乘以idf值:
\[TF-IDF=tf*idf\]
前面提到,将文档向量化,需要给文档中的每个词赋一个实数值,这个实数值,就是通过tf*idf得到。
4. 总结
在给定文档集合C和词典D的条件下,将某篇文档通过词袋模型表示成一个个的词,而后根据 TF-IDF 为每个词计算出一个实数值;
由于词典D的大小为M,因此将这篇文档转化成一个M维向量,如果词典中某个词未出现在文档中,则这个词的在向量中对应的元素为0,若某个词出现在文档中,则这个词在向量中对应的元素值为这个词的tf-idf值。这样,就把文档表示成向量了,而这就是 向量空间模型(vector space model)
而有了,文档向量,也就可以用余弦公式计算文档之间的相似度了。
由于词典一般比较大,比如20万个词左右的汉语词典,而一篇文档中一般只包含几百个词,因此可看出:文档向量是很稀疏的。
另外,由于对于文档而言,词与词之间是有顺序的,比如文档开头是哪些词,中间有哪些词,结尾又是哪些词,但表示成向量之后,这个 顺序 信息丢失了。比如下面2篇文档,它们的文档向量是一样的。
Mary is quick than John
John is quick than Mary
参考:《An Introduction to Information Retrieval》第6章