使用R提取最频繁的ngrams的高效方法

时间:2015-11-08 18:18:21

标签: r performance tm n-gram rweka

我使用以下tm + RWeka代码来提取文本中最常见的ngram:

library("RWeka")
library("tm")

text <- c('I am good person','I am bad person','You are great','You are more great','todo learn english','He is ok')
BigramTokenizer <- function(x) NGramTokenizer(x,Weka_control(min=2,max=2))
corpus <- Corpus(VectorSource(text))
tdm <- TermDocumentMatrix(corpus,control = list(tokenize = BigramTokenizer))

DF <- data.frame(inspect(tdm))
DF$sums <- DF$X1+DF$X2+DF$X3+DF$X4+DF$X5+DF$X6
MostFreqNgrams <- rownames(head(DF[with(DF,order(-sums)),]))

它工作正常,但如果数据更大呢?有计算更有效的方法吗?此外,如果变量更多(例如100),我如何编写DF$sums代码行。肯定会有比以下更优雅的东西:

DF$sums <- DF$X1+DF$X2+DF$X3+DF$X4+DF$X5+DF$X6+...+DF$X99+DF$X100

谢谢

编辑:我想知道是否有办法从tdm TermDocumentMatrix中提取最频繁的ngrams并在创建带有值的数据帧之后。我正在做的是创建一个包含所有ngrams的数据框,然后采用最常见的值,这似乎不是最佳选择。

2 个答案:

答案 0 :(得分:1)

使用 quanteda 包进行文本分析有一种更简单,更有效的方法。

> require(quanteda)
> dtm <- dfm(text, ngrams = 2)
Creating a dfm from a character vector ...
   ... lowercasing
   ... tokenizing
   ... indexing documents: 6 documents
   ... indexing features: 13 feature types
   ... created a 6 x 13 sparse dfm
   ... complete. 
Elapsed time: 0.007 seconds.
> topfeatures(dtm, n = 10)
       i_am     you_are     am_good good_person      am_bad  bad_person   are_great    are_more 
          2           2           1           1           1           1           1           1 
 more_great  todo_learn 
          1           1 

结果矩阵稀疏且非常有效。在GitHub版本中,ngrams()函数(由dfm()调用)在C ++中实现了速度,因此速度更快。

答案 1 :(得分:0)

根据您的编辑,您可以使用以下内容:

my_matrix <- as.matrix(tdm[findFreqTerms(tdm, lowfreq = 2),])
DF <- data.frame(my_matrix, sums = rowSums(my_matrix))
DF
        X1 X2 X3 X4 X5 X6 sums
i am     1  1  0  0  0  0    2
you are  0  0  1  1  0  0    2