大文档术语矩阵 - 计算文档字符数时出错

big document term matrix - error when counting the number of characters of documents

我用包 RTextTools.

建立了一个很大的文档术语矩阵

现在我正在尝试计算矩阵行中的字符数,以便我可以在执行主题建模之前删除空文档。

当我将代码应用于我的语料库样本并获得较小的矩阵时,我的代码没有给出任何错误,但是当我尝试计算从我的整个语料库生成的矩阵中文档的行长时(~75000 条推文) ) 我收到以下错误消息:

Error in vector(typeof(x$v), nr * nc) : 
  the dimension of the vector no cannot be NA
And: Warning message:
In nr * nc : NA produced by integer overflow

这是我的代码:

matrix <- create_matrix(data$clean_text, language="french", stemWords=TRUE, removeStopwords=TRUE, removeNumbers=TRUE, stripWhitespace=TRUE, toLower=TRUE, removePunctuation=TRUE, minWordLength=3)

rowTotals <- apply(matrix, 1, sum)

如果我尝试使用包含 25000 个文档的矩阵,我会收到以下错误:

message: rowTotals <- apply(matrix, 1, sum) 
Errore: cannot allocate vector of size 7.1 Gb

如果将数据保存在 dtm 中,您也许可以解决这个问题,dtm 使用稀疏矩阵表示,其内存效率比常规矩阵高得多。

apply 函数给出错误的原因是因为它将稀疏矩阵转换为常规矩阵(Q 中的 matrix 对象 - 顺便说一句,给数据对象命名是一种糟糕的风格这也是函数的名称,尤其是基函数)。这意味着 R 必须为 dtm 中的所有零分配内存(通常大部分是零,因此其中有很多内存)。对于稀疏矩阵 R 不需要存储任何零。

这是 apply 源代码的前几行,请参阅此处的最后一行以转换为正则矩阵:

apply
function (X, MARGIN, FUN, ...) 
{
    FUN <- match.fun(FUN)
    dl <- length(dim(X))
    if (!dl) 
        stop("dim(X) must have a positive length")
    if (is.object(X)) 
        X <- if (dl == 2L) 
            as.matrix(X) # this is where your memory gets filled with zeros

那么如何避免这种转换呢?这是在保持稀疏矩阵格式的同时遍历行以获得它们的总和的一种方法:

sapply(seq(nrow(matrix)), function(i) sum(matrix[i,]))
[1] 2 1 2 2 1

以这种方式进行子集化保留了稀疏格式,并且不会将对象转换为更耗内存的公共矩阵表示。我们可以检查表示:

str(matrix[1,])
List of 6
 $ i       : int [1:2] 1 1
 $ j       : int [1:2] 1 3
 $ v       : num [1:2] 1 1
 $ nrow    : int 1
 $ ncol    : int 6
 $ dimnames:List of 2
  ..$ Docs : chr "1"
  ..$ Terms: chr [1:6] "document" "file" "first" "second" ...
 - attr(*, "class")= chr [1:2] "DocumentTermMatrix" "simple_triplet_matrix"
 - attr(*, "weighting")= chr [1:2] "term frequency" "tf"

所以在 sapply 函数中,我们总是在处理稀疏矩阵。即使 sum(或您在那里使用的任何函数)进行某种转换,它也只会转换 dtm 的一行,而不是整行。

在 R 中处理大型文本数据时的一般原则是将 dtm 保持为稀疏矩阵,然后您应该能够保持在内存限制内。