NLP ----- TF-IDF

   作为文本处理比较经典的方法,本文通过手动构造 tf_idf 矩阵和 R 的 tm包当中提供的 DocumentTermMatrix 函数方法的构造进行对比,来一种比较直观的解读.

   1.构造原始文本数据 

doc_1 <- "见鬼了"
doc_2 <- "我见鬼了"
doc_3 <- "我真的见鬼了"
text_data <- c(doc_1, doc_2, doc_3)

  2. 数据分词构建文档-词项矩阵  

library(tm)
library(Rwordseg)
text_data <- segmentCN(text_data)
corpus <- Corpus(VectorSource(text_data))
dtm <- DocumentTermMatrix(corpus)
inspect(weightTfIdf(dtm))
<<DocumentTermMatrix (documents: 3, terms: 6)>>
Non-/sparse entries: 4/14
Sparsity           : 78%
Maximal term length: 1
Weighting          : term frequency - inverse document frequency (normalized) (tf-idf)
Sample             :
    Terms
Docs 了         我        的        真 见 鬼
   1  0 0.00000000 0.0000000 0.0000000  0  0
   2  0 0.14624063 0.0000000 0.0000000  0  0
   3  0 0.09749375 0.2641604 0.2641604  0  0

    如果不清楚 tf_idf 具体怎么计算的, 可以通过上述代码步骤就无脑得到一个矩阵, 但是知其然而不知其所以然, 怎么可以?下面根据 tf_idf 公式定义, 手动制造一个看看结果与上述是否相符.

    tf_idf,其实是两个部分, 一个是tf, 一个是idf.把它们的乘积定义为tf_idf. 

1. tf顾名思义就是文档中的词频公式如下: 

         TF_{ij} = \frac{n_{i,j}}\sum_k n_{k, j}

2. idf逆向文件频率, 用于剔除掉文档之间共现的词, 以此保证单个文档中词的具有良好的区分能力.计算公式如下:

         IDF_{i} = log\frac{|D|}{\left \{ j:t_{i} \epsilon d_{j} \right \}}

tf <- matrix(c(1/3, 0, 0, 0, 1/3, 1/3, 1/4, 1/4, 0, 0, 1/4, 1/4, 1/6, 1/6, 1/6, 1/6, 1/6, 1/6), 3, 6, byrow = TRUE)
idf <- c(log2(3/3), log2(3/2), log2(3/1), log2(3/1), log2(3/3), log2(3/3))
 t(t(tf) * idf)
    [,1]       [,2]      [,3]      [,4] [,5] [,6]
[1,]    0 0.00000000 0.0000000 0.0000000    0    0
[2,]    0 0.14624063 0.0000000 0.0000000    0    0
[3,]    0 0.09749375 0.2641604 0.2641604    0    0

    代码中的 tf 矩阵根据对文本one-hot 后除以其文本长度, 也就是对tf公式的实现. idf 中的log 使用以2为底数, 对数中分子表示文档的总数目, 分子表示词袋中词在所有文档中出现的总频率. 这里因为 R 的向量是列向量.所以直接对 tf矩阵乘以idf会按照tf的每一列去广播idf向量.所以采用两次转置.

    最终结果是一样的.同时发现结果中会把文档之间共存的词权重数值都归了零, 留下了可以对该文档进行表示的词.其实这就是idf的作用, 而tf本身的作用只是对这些数据做了归一化.




猜你喜欢

转载自blog.csdn.net/qq_24834541/article/details/80336108
今日推荐