给你若干篇文档,找出这些文档中最类似的两篇文档?html
类似性,能够用距离来衡量。而在数学上,可以使用余弦来计算两个向量的距离。apache
\[cos(\vec a, \vec b)=\frac {\vec a*\vec b}{||\vec a||*||\vec b||}\]ui
所以,用向量来表示文档,而后就能够用余弦来计算两篇文章之间的类似度了。spa
一篇文档里面有不少不少句子,每一个句子又是由一个个的词组成。词袋模型,通俗地讲,就是:把一篇文档当作词袋,里面装着一个个的词。orm
从而,将一篇文档转化成了一个个的词(或者称之为 term),显然地,文档转化成一个个的词以后,词与词之间的顺序关系丢失了。htm
在计算文档之间类似度以前,会有一些前提条件:blog
向量是有长度的,向量中的每一个元素是数值,好比一个三维实值向量:(1.2,2.8,4.5)文档
首先将文档经过词袋模型转化成一个个的词,通常地,因为文档中的词都会存在于词典D中,定义一个M维向量(M等于词典大小),若文档中的某个词在词典中出现了,就给这个词赋一个实数值。若未出现,则在相应位置处赋值为0字符串
在给定的文档集合C和词典D的状况下,如何来衡量一个词(term)的权重呢?即如何计算这个实数值呢?get
tf(term frequency),是指 term 在某篇文档中出现的频率。假设文档集合中共有10篇文章,词:''国家'',在文档1中出现了6次,那么对于文档1而言,'国家'这个词的tf值为6。所以,tf 是针对单篇文档而言的,即:某个词在这篇文档中出现了多少次。词频是计算文档得分的一个因子,所以为了计算某篇文档的得分,使用的词频指的就是term在这篇文档中出现的次数,而不是term在全部文档中出现的次数。
'国家'这个词在文档1中的idf值 由 词(term) 出如今各个文档中数目来决定,好比'国家'一共在8篇文档中出现了,那么对于文档1而言,'国家'这个词的idf值由以下公式计算:
\[idf_t=log\frac{N}{df_t}\]
其中,N=10 表示文档集合中共有10篇文章。\(df_t=8\),表示 term 国家 在8篇文档中出现了。所以,idf 值是针对全部文档(文档集合)而言的,即:数一数这个词都出如今哪些文档中。
而TF-IDF,就是将tf值乘以idf值:
\[TF-IDF=tf*idf\]
前面提到,将文档向量化,须要给文档中的每一个词赋一个实数值,这个实数值,就是经过tf*idf获得。
在给定文档集合C和词典D的条件下,将某篇文档经过词袋模型表示成一个个的词,然后根据 TF-IDF 为每一个词计算出一个实数值;
因为词典D的大小为M,所以将这篇文档转化成一个M维向量,若是词典中某个词未出如今文档中,则这个词的在向量中对应的元素为0,若某个词出如今文档中,则这个词在向量中对应的元素值为这个词的tf-idf值。这样,就把文档表示成向量了,而这就是 向量空间模型(vector space model)。从这里也可看出:向量空间模型并无catch住词(term)与词(term)之间的关系,它假设各个term之间是相互独立的。即:VSM implies the assumption on the independence between terms
而有了文档向量,也就能够用余弦公式计算文档之间的类似度了。
因为词典通常比较大,好比20万个词左右的汉语词典,而一篇文档中通常只包含几百个词,所以可看出:文档向量是很稀疏的。
另外,因为对于文档而言,词与词之间是有顺序的,好比文档开头是哪些词,中间有哪些词,结尾又是哪些词,但表示成向量以后,这个 顺序 信息丢失了。好比下面2篇文档,它们的文档向量是同样的。
Mary is quick than John
John is quick than Mary
总之,在我看来,向量空间模型是一种将文档转化成向量的方式,文档转化成了向量,从而能够在同一维度的空间中表示一个个的文档。向量中的每一个元素是一个个的实数,每一个元素对应着一个 词(term),实数 是经过tf-idf计算出来的。由此看来,tf-idf也仅仅是一种将词(term)转化成实数的方式,固然咱们也能够经过其余方法将 词 转化成实数。而这里的 词 则是由词典定义的,若词典中的某个词 在文档中,则计算这个词的tf-idf值,若某个词不在文档中,则这个词对应的向量元素为0。所以,获得的文档向量是M维的,其中M就是词典的大小---词典中词的个数。
将文档转化成了向量,文档之间的比较,就能够转化成向量的比较。所以,就能回答给定若干篇文档,哪两篇文档最相关这样的问题了。在实际应用中,好比Lucene中的TF-IDF Similarity就是基于VSM来实现的。从VSM Model到Lucene Conceptual Scoring Formula 再到 Lucene Practical Scoring Formula,解释了在实际应用中,咱们输入一个查询字符串,Lucene是如何计算文档的得分,从而找出与查询字符串最相关的文档的。
在实际应用中,咱们并非直接使用 TF*IDF 这个理论模型,由于它计算出来的权重偏向于短文本,所以须要某种平滑。
举个例子来讲,term1在docA中出现了3次,term2在docA中出现了9次,根据上面计算TF的方式,意味着:term2的tf权重(或者说重要性)比term1要大3倍,那真的是重要3倍么?所以,在Lucene的实际评分模型中,计算的是sqrt(tf),即经过 tf 开根号,起到必定的平滑做用。相似地,计算 idf 时,是取log对数,也是为了平滑。
参考资料: