从TermDocumentMatrix创建稀疏矩阵

5
我使用R语言的tm库创建了一个TermDocumentMatrix。它看起来像这样:<p>
> inspect(freq.terms)

A document-term matrix (19 documents, 214 terms)

Non-/sparse entries: 256/3810
Sparsity           : 94%
Maximal term length: 19 
Weighting          : term frequency (tf)

Terms
Docs abundant acid active adhesion aeropyrum alternative
  1         0    0      1        0         0           0
  2         0    0      0        0         0           0
  3         0    0      0        1         0           0
  4         0    0      0        0         0           0
  5         0    0      0        0         0           0
  6         0    1      0        0         0           0
  7         0    0      0        0         0           0
  8         0    0      0        0         0           0
  9         0    0      0        0         0           0
  10        0    0      0        0         1           0
  11        0    0      1        0         0           0
  12        0    0      0        0         0           0
  13        0    0      0        0         0           0
  14        0    0      0        0         0           0
  15        1    0      0        0         0           0
  16        0    0      0        0         0           0
  17        0    0      0        0         0           0
  18        0    0      0        0         0           0
  19        0    0      0        0         0           1

这只是我正在处理的214个术语矩阵中的一个小样本。在小规模下,这样做没问题。如果我想将我的TermDocumentMatrix转换为普通矩阵,我需要执行以下操作:

data.matrix <- as.matrix(freq.terms)

然而,我展示的数据仅仅是整个数据集的一部分。我的整个数据集可能至少有10,000个术语。当我尝试从整个数据集中创建一个词频矩阵时,会出现错误:

> Error cannot allocate vector of size n Kb

因此,我正在寻找其他有效的内存分配方式来为我的tdm进行优化。我尝试了使用Matrix库将我的tdm转换成稀疏矩阵,但遇到了同样的问题。在这一点上,我的备选方案是什么?我觉得我应该调查以下其中之一:
- `bigmemory` / `ff`软件包,如这里所述(尽管目前似乎无法在Windows上使用`bigmemory`软件包) - `irlba`软件包用于计算我的tdm的部分奇异值分解,如这里所述。
我已经尝试过两个库中的函数,但似乎都没有达到实质性进展。有人知道最好的前进方式吗?我花了很长时间在这方面摸索,所以在我继续朝错误的方向浪费更多时间之前,我想问问那些有更多大数据集处理经验的人。
编辑:更改10,00为10,000。感谢@nograpes。

1
我想你的意思是一万个术语。你要处理多少个文档?我认为在这里进行一些预处理会更容易:在创建完整矩阵之前,剪切掉一些非常罕见的术语。然后,您可以剪切掉与您试图从数据中提取的内容相关性较低的术语。 - nograpes
@nograpes 是的,一万个术语,我现在会进行编辑。经过进一步阅读(尤其是这里),我认为你是对的;唯一的方法是从矩阵中删除一些非必要的术语。我想我的担心是,将来我可能会使用更大的数据集;如果至少有10,000个术语是必要的(不稀疏的),那么会发生什么?无论如何,感谢您的评论。 - user1988898
共现集中有多少个非零条目?我记得在N约为20百万时,使用Matrix(稀疏)包取得了不错的结果。不过下次我打算尝试使用data.table。 - Clayton Stanley
也许最简单的方法(对我们来说)是编写一些代码,生成一些具有大致相同特征的随机文档。然后,我们可以测试一些解决方案,并展示您尝试过的稀疏矩阵解决方案。老实说,对于具有“典型”(即我有限的经验所见)稀疏性的文档而言,一万个术语的稀疏矩阵不应该太大。 - nograpes
1个回答

1

包qdap似乎能够处理这么大的问题。首先需要重新创建一个与OP问题相匹配的数据集,然后提供解决方案。从qdap版本1.1.0开始,它与tm包兼容:

library(qdapDictionaries)

FUN <- function() {
   paste(sample(DICTIONARY[, 1], sample(seq(100, 10000, by=1000), 1, TRUE)), collapse=" ")
}

library(qdap)
mycorpus <- tm::Corpus(tm::VectorSource(lapply(paste0("doc", 1:15), function(i) FUN())))

这段内容是关于编程的。它讲述了如何使用 qdap 方法来创建一个 TermDocumentMatrix。首先需要将 Corpus 转换为 dataframe,然后使用 tdm 函数来创建 TermDocumentMatrix。
out <- with(tm_corpus2df(mycorpus), tdm(text, docs))
tm::inspect(out)

## A term-document matrix (19914 terms, 15 documents)
## 
## Non-/sparse entries: 80235/218475
## Sparsity           : 73%
## Maximal term length: 19 
## Weighting          : term frequency (tf)

我遇到了与 OP 相似的问题。当我使用 tm 包并检查语料库(match_names <- inspect(DocumentTermMatrix(docs, list(dictionary = names))))时,我的 RAM 用完了。如果我使用您的代码(更新为 QDAP 的新版本),我会生成 out <- with(as.data.frame(mycorpus), as.dtm(match_names, names)),我发现在 dtm 中出现了许多不在原始 names 字符向量字典中的单词。我做错了什么吗? - wake_wake

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接