从R topicmodels中删除DocumentTermMatrix中的空文档?

Bil*_*l M 40 r lda topic-modeling topicmodels

我正在使用R中的topicmodels包进行主题建模.我正在创建一个Corpus对象,进行一些基本的预处理,然后创建一个DocumentTermMatrix:

corpus <- Corpus(VectorSource(vec), readerControl=list(language="en")) 
corpus <- tm_map(corpus, tolower)
corpus <- tm_map(corpus, removePunctuation)
corpus <- tm_map(corpus, removeWords, stopwords("english"))
corpus <- tm_map(corpus, stripWhitespace)
corpus <- tm_map(corpus, removeNumbers)
...snip removing several custom lists of stopwords...
corpus <- tm_map(corpus, stemDocument)
dtm <- DocumentTermMatrix(corpus, control=list(minDocFreq=2, minWordLength=2))
Run Code Online (Sandbox Code Playgroud)

然后执行LDA:

LDA(dtm, 30)
Run Code Online (Sandbox Code Playgroud)

最后调用LDA()返回错误

  "Each row of the input matrix needs to contain at least one non-zero entry". 
Run Code Online (Sandbox Code Playgroud)

我认为这意味着在预处理之后至少有一个文档中没有任何术语.有没有一种简单的方法可以从DocumentTermMatrix中删除不包含任何术语的文档?

我查看了topicmodels包的文档,找到了函数removeSparseTerms,它删除了任何文档中没有出现的术语,但没有类似的删除文档.

ags*_*udy 59

"Each row of the input matrix needs to contain at least one non-zero entry"
Run Code Online (Sandbox Code Playgroud)

该错误意味着稀疏矩阵包含没有条目(单词)的行.一个想法是按行计算单词总和

rowTotals <- apply(dtm , 1, sum) #Find the sum of words in each Document
dtm.new   <- dtm[rowTotals> 0, ]           #remove all docs without words
Run Code Online (Sandbox Code Playgroud)

  • 该解决方案存在一个潜在问题:没有零字文档的结果矩阵将不再对应于原始语料库,即,它将具有较少数量的行.因此,不可能使用LDA的结果对语料库进行分类(例如,通过为每个文档分配最佳聚类).关于如何解决这个问题的任何想法? (5认同)
  • 我收到这个错误:`向量中的rror(typeof(x $ v),nr*nc):向量大小不能为NA另外:警告消息:在nr*nc中:由整数溢出产生的NAs (3认同)
  • 在一行中,不使用apply:`dtm [rowSums(dtm)> 0,]` (2认同)

小智 23

agstudy的答案效果很好,但在慢速计算机上使用它证明是有问题的.

tic()
row_total = apply(dtm, 1, sum)
dtm.new = dtm[row_total>0,]
toc()
4.859 sec elapsed
Run Code Online (Sandbox Code Playgroud)

(这是用4000x15000 dtm完成的)

瓶颈似乎适用sum()于稀疏矩阵.

tm包创建的文档 - 术语矩阵包含名称i和j,它们是条目在稀疏矩阵中的索引.如果dtm$i不包含特定的行索引p,则row p为空.

tic()
ui = unique(dtm$i)
dtm.new = dtm[ui,]
toc()
0.121 sec elapsed
Run Code Online (Sandbox Code Playgroud)

ui包含所有非零索引,并且由于dtm$i已经订购,因此dtm.new将采用相同的顺序dtm.对于较小的文档术语矩阵,性能增益可能无关紧要,但对于较大的矩阵可能会变得很重要.


Dar*_*can 12

这只是为了详细说明agstudy给出的答案.

我们可以在执行第二个仅包含非空文档的dtm之前,识别我们语料库中长度为零的文档并直接从语料库中删除文档,而不是从dtm矩阵中删除空行.

这对于保持dtm和语料库之间的1:1对应是有用的.

empty.rows <- dtm[rowTotals == 0, ]$dimnames[1][[1]] corpus <- corpus[-as.numeric(empty.rows)]