检查{tm} R包中术语的稀疏性

时间:2016-10-30 02:32:30

标签: r tm

这是一个相当具体的问题,但希望它也与其他人有关......

有没有人知道是否有一种简单的方法可以找到一个术语出现在带有{tm}包的语料库中的文档数量?

基本上,如果我有一个我构建的Term-Document Matrix,我想看看该行对于特定术语的稀疏程度,即矩阵中有多少列具有该行的非零值。 for循环显然可以正常工作,但是我正在使用一个非常大的矩阵,因此在循环中重复进行子集化会让CPU感到厌烦。

实际上......(对上述问题的回答很好,但是)我真正想要做的就是在矩阵中为每个术语获取该数字。现在我正在使用:

TDM <- TermDocumentMatrix(somecorpus)

terms <- TDM$dimnames$Terms

idf <- data.frame(term = terms, freq = numeric(length(terms)), stringsAsFactors = F)

for (i in 1:nrow(idf)) {
  aa <- as.matrix(TDM[,idf$term[i]])
  idf$freq[i] <- length(aa[aa[,1]>0, ])
}

这有效,但需要 looong 时间。还有更好的想法? 提前致谢, 塞特

2 个答案:

答案 0 :(得分:0)

啊!我想到了! TDM被存储为稀疏矩阵,因此您只需为列表创建列的频率表。这至少可以为您提供每个索引的计数,然后您只需将索引与条件匹配即可。

tc <- as.data.frame(table(TDM$i)) 

感谢所有看过这个的人。希望将来对某人有所帮助。

答案 1 :(得分:0)

您正在尝试获取称为文档频率的数量:术语出现的文档数。最简单的方法是获取在术语 - 文档矩阵中出现术语的维度上的非零单元格的总和。 (我这样说,因为如果你把它形成一个文档 - 术语矩阵,术语将是列,这是更好的方法!)

使用apply()使用as.data.frame()rowSums()可以获得更快的结果:

require(tm)
data(crude)
TDM <- TermDocumentMatrix(crude)
dfreq1 <- rowSums(as.matrix(TDM > 0))
head(dfreq1, 10)
##   ...      "(it)    "demand "expansion       "for    "growth        "if 
##     2          1          1          1          1          1          1 
##   "is       "may      "none 
##     2          1          2 

quanteda 文本分析包有一个内置函数,称为docfreq(),它更容易,更快:

require(quanteda)
DFM <- dfm(corpus(crude), verbose = FALSE)
head(docfreq(DFM), 10)           
## diamond  shamrock      corp      said      that effective     today        it 
##       1         1         2        20        11         4         7        13 
##     had       cut 
##       4         3 

请注意dfm()应用标点符号和数字删除,并将文本缩小,为简单起见,我不适用于上面的 tm 示例。