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

是否从R topicmodels中的DocumentTermMatrix中删除空文档?,r,lda,topic-modeling,topicmodels,R,Lda,Topic Modeling,Topicmodels,我正在使用R中的topicmodels包进行主题建模。我正在创建一个语料库对象,进行一些基本的预处理,然后创建一个DocumentTermMatrix: corpus <- Corpus(VectorSource(vec), readerControl=list(language="en")) corpus <- tm_map(corpus, tolower) corpus <- tm_map(corpus, removePunctuation) corpus <- t

我正在使用R中的topicmodels包进行主题建模。我正在创建一个语料库对象,进行一些基本的预处理,然后创建一个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))
对LDA()的最后一次调用返回错误

  "Each row of the input matrix needs to contain at least one non-zero entry". 
我假设这意味着在预处理之后,至少有一个文档中没有术语。有没有一种简单的方法可以从DocumentTermMatrix中删除不包含任何术语的文档

我在文档中查找了topicmodels包,发现了函数removeSparseTerms,它可以删除任何文档中都没有出现的术语,但是没有类似的删除文档的方法

"Each row of the input matrix needs to contain at least one non-zero entry"
该错误意味着稀疏矩阵包含一行,但没有条目(单词)。一种方法是按行计算单词的总和

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

rowTotals这只是对agstudy给出的答案进行详细说明

我们不需要从dtm矩阵中删除空行,而是可以识别语料库中长度为零的文档,并直接从语料库中删除文档,然后再对非空文档执行第二次dtm

这有助于在dtm和语料库之间保持1:1的对应关系


empty.rows只是Dario Lacan答案的小附录:

empty.rows <- dtm[rowTotals == 0, ]$dimnames[1][[1]]
如果您使用连续编号构建自己的语料库,在数据清理之后,一些文档可以被删除,编号也将被破坏。因此,最好直接使用
id

corpus <- tm_filter(
  corpus,
  FUN = function(doc) !is.element(meta(doc)$id, empty.rows))
  # !( meta(doc)$id %in% emptyRows )
)

corpus只要从DTM中删除稀疏项,所有这些都会很好地工作

dtm <- DocumentTermMatrix(crude, sparse=TRUE)

dtmagstudy的答案效果很好,但在速度较慢的计算机上使用它却有轻微的问题

tic()
row_total = apply(dtm, 1, sum)
dtm.new = dtm[row_total>0,]
toc()
4.859 sec elapsed
(这是使用4000x15000 dtm完成的)

瓶颈似乎是将
sum()
应用于稀疏矩阵

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

tic()
ui = unique(dtm$i)
dtm.new = dtm[ui,]
toc()
0.121 sec elapsed

ui
包含所有非零索引,并且由于已经订购了
dtm$i
dtm。新的
将与
dtm
的顺序相同。对于较小的文档术语矩阵,性能增益可能并不重要,但对于较大的矩阵,性能增益可能会变得显著。

我在数据框
lt$title
中有一列包含字符串。我在此列中没有“空”行,但仍然出现错误:

LDA中的错误(dtm,k=20,control=list(seed=813)):每行 输入矩阵需要至少包含一个非零条目

上面的一些解决方案对我不起作用,因为我需要将预测主题的向量加入到我的原始数据框架中。因此,从文档术语矩阵中删除非零条目是没有选择的

问题是,
lt$title
中的一些(非常短)字符串包含特殊字符,无法由
Corpus()
和/或
DocumentTermMatrix()
处理

我的解决方案是删除“短”字符串(最多一个或两个单词),这些字符串无论如何都不会携带太多信息

# Clean up text data
lt$test=nchar(lt$title)
lt = lt[!lt$test<10,]
lt$test<-NULL

# Topic modeling
corpus <- Corpus(VectorSource(lt$title))
dtm = DocumentTermMatrix(corpus)
tm = LDA(dtm, k = 20, control = list(seed = 813))

# Add "topics" to original DF
lt$topic = topics(tm)
#清理文本数据
lt$test=nchar(lt$title)

lt=lt[!lt$test检查时(语料库),你看到一些emty文档了吗?LDA在哪个包中?我正在使用topicmodels包中的函数LDA。我有大约51000个文档,所以我不能用inspect手动检查。另外,一些术语可能被minDocFreq=2,minWordLength=2参数删除,所以我真正想检查的是DocumentTermMatrix。有没有其他方法来查找空文档?这很好。我没想到DocumentTermMatrix可以像那样编制索引。谢谢!@BillM这是一个矩阵,特别是(稀疏),但仍然是一个矩阵。此解决方案有一个潜在问题:没有零字文档的结果矩阵将不再对应于原始语料库,即,它将具有较少的行数。因此,无法使用LDA的结果对语料库进行分类(例如,通过为每个文档分配最佳集群)有没有办法解决这个问题?我收到了这个错误:
error in vector(typeof(x$v),nr*nc):向量大小不能是NA另外:警告消息:在nr*nc:NAs中,整数溢出在一行中产生,而不使用apply:
dtm[行和(dtm)>0,]
对于我来说,代码的第二行在
[.VCorpus
(语料库,1,1):未使用的参数(1)中抛出了此错误。我将其修改为语料库语料库语料库是一个列表,所以您不能使用二维选择。您只需要
语料库[-as.numeric(empty.rows)]
(即一维).dtm此解决方案在所需内存方面优于上一个解决方案!
tic()
ui = unique(dtm$i)
dtm.new = dtm[ui,]
toc()
0.121 sec elapsed
# Clean up text data
lt$test=nchar(lt$title)
lt = lt[!lt$test<10,]
lt$test<-NULL

# Topic modeling
corpus <- Corpus(VectorSource(lt$title))
dtm = DocumentTermMatrix(corpus)
tm = LDA(dtm, k = 20, control = list(seed = 813))

# Add "topics" to original DF
lt$topic = topics(tm)