如何使用MapReduce计算文本的tf-idf
版权声明:本文所有内容都是原创,如有转载请注明出处,谢谢。
本文介绍如何使用MapReduce进行文本的tf-idf计算。 程序的输入是一个个的文本,类似下面的:
doc1: w1, w2, w3
doc2: w4, w5, w6
输出为一个个的Vector,可以是Sparse的Vector,或者是Dense Vector, 我们就假设使用Sparse的Vector,输出如下:
doc1_id, 1:0.1, 2:0.1, 3:0.03
doc2_id, 4:0.1, 5:0.1, 6:0.01
如何使用MapReduce进行计算呢?
对一个单词$w_i$, 在文档$D_j$中,tf-idf的计算公式如下: $$ tf_idf= \frac{ N(w_i) } { N( D_j ) } * \log \frac{ \vert D \vert } { \vert j: w_i \in D_j \vert + 1 } $$ 其中$N(w_i)$ 是$w_i$在$D_j$中的频率,$N(D_j)$是$D_j$中所有词的频率,也就是文本的长度, $|D|$为所有文本的个数,$| j: w_j \in D_j |$ 为包含$w_i$的文档个数。
统计tf-idf需要两个MapReduce Job,一个job统计每个词的tf-idf,然后将每个文档中的词聚合到一起。
1 2 3 4 5 |
|
其中 doc1_id根据对文档名字进行hash得到,tf_w1根据doc1中w1出现的次数来计算, w1_index根据词典计算,context的counter统计文档数量|D|
MapReduce1 Reducer Output:
doc1_id: (w1_index, tf-idf )
tf-idf根据tf, |D|,所有包含w1的文档的个数
MapReduce2 Mapper: Identity Mapper
MapReduce2 Reducer: 根据doc_id,将所有相同文档归并到一起,得到:
doc1_id: w1_index:tf-idf, w2_index:tf-idf
doc2_id: w4_index:tf-idf, w5_index:tf-idf
还有另外一种方法是,先计算每个词的idf,然后再将idf做为distributed cache 分发给每一个mapper,然后得到每个文本的tf-idf.