【问题标题】:Creating a sparse matrix from a TermDocumentMatrix从 TermDocumentMatrix 创建稀疏矩阵
【发布时间】:2014-02-10 21:13:09
【问题描述】:

我从 R 中的 tm 库创建了一个 TermDocumentMatrix。它看起来像这样:

> 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 个术语。当我尝试从整体数据创建 TDM 时,出现错误:

> Error cannot allocate vector of size n Kb

因此,从这里开始,我正在寻找为我的 tdm 寻找有效内存分配的替代方法。

我尝试将我的 tdm 转换为来自 Matrix 库的稀疏矩阵,但遇到了同样的问题。

此时我有哪些替代方案?我觉得我应该调查以下之一:

  • bigmemory/ff 包与here 讨论的一样(尽管bigmemory 包目前似乎不适用于 Windows)
  • irlba 包用于计算我的 tdm 的部分 SVD,如提到的 here

我已经对这两个库中的函数进行了试验,但似乎没有得到任何实质性的结果。有谁知道最好的前进方式是什么?我花了很长时间摆弄这个问题,以至于我想在我浪费更多时间在错误的方向上之前,我会问那些比我更有经验的人处理大型数据集。

编辑:将 10,00 更改为 10,000。谢谢@nograpes。

【问题讨论】:

  • 我想你的意思是 10,000 个术语。你在看多少文件?我认为在这里进行一些预处理是最容易的:在创建完整矩阵之前,删除一些非常罕见的术语。然后,您可以删除与您试图从数据中提取的任何内容相关性较低的术语。
  • @nograpes 是的 10,000 个术语,我现在将对其进行编辑。做了一些进一步的阅读(特别是here)我认为你是对的;唯一的方法是从我的矩阵中删除一些非必要的术语。我想我担心的是将来我可能会使用更大的数据集;当我的至少 10,000 个术语是必不可少的(不是稀疏的)时会发生什么?不管怎样,谢谢你的评论。
  • 共现集中有多少个非零条目?我使用 N 约为 20Mil IIRC 的 Matrix(稀疏)包取得了很好的效果。不过,我计划下次尝试使用 data.table。
  • 如果您编写一些代码来生成一些具有您所看到的特征的随机文档,这可能是最简单的(对我们而言)。然后,我们可以测试一些解决方案,您可以向我们展示您对稀疏矩阵解决方案的尝试。老实说,对于具有“典型”(即我在有限的经验中看到的)稀疏性的文档来说,一个 10,000 词的稀疏矩阵不应该那么大。

标签: r sparse-matrix tm term-document-matrix


【解决方案1】:

qdap 包似乎能够处理这么大的问题。第一部分是重新创建与 OP 的问题匹配的数据集,然后是解决方案。截至qdap version 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 方法。您必须先将语料库转换为数据框 (tm_corpus2df),然后使用 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 &lt;- inspect(DocumentTermMatrix(docs, list(dictionary = names)))) 时,我的 RAM 用完了。如果我使用您的代码(更新到 QDAP 的新版本),我会生成 out &lt;- with(as.data.frame(mycorpus), as.dtm(match_names, names)) ,我发现在 dtm 中出现了很多不在原始 names 字符向量字典中的单词。我做错了吗?
猜你喜欢
  • 2017-03-31
  • 2012-01-10
  • 1970-01-01
  • 2017-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-29
  • 2014-11-30
相关资源
最近更新 更多