1

我正在为 Naive Bayes 实现创建一个文档术语矩阵(简称 dtm)(我知道有一个函数,但我必须自己编写代码以完成作业。)我编写了一个成功创建 dtm 的函数,问题是结果矩阵占用了太多内存。例如,一个 100 x 32000 矩阵(由 0 和 1 组成)的大小为 24MB!当尝试使用完整的 10k 文档时,这会导致 r 中的崩溃行为。下面是函数,最后 3 行是一个玩具示例。谁能发现为什么特别是“稀疏”函数会返回如此大量内存的结果?

listAllWords <- function(docs)
{
  str1 <- strsplit(x=docs, split="\\s", fixed=FALSE)
  dictDupl <- unlist(str1)[!(unlist(str1) %in% stopWords)]
  dictionary <- unique(dictDupl)
}

#function to create the sparse matrix of words as they appear in each article segment
sparser <- function (docs, dictionary) 
{
  num.docs <- length(docs) #dtm rows
  num.words <- length(dictionary) #dtm columns
  dtm <- mat.or.vec(num.docs,num.words) # Instantiate dtm of zeroes
  for (i in 1:num.docs)
  {
    doc.temp <- unlist(strsplit(x=docs[i], split="\\s", fixed=FALSE)) #vectorize words
    num.words.doc <- length(doc.temp)
    for (j in 1:num.words.doc)
    {
      ind <- which(dictionary == doc.temp[j]) #loop over words and find index in dict.
      dtm[i,ind] <- 1 #indicate this word is in this document
    }
  }
  return(dtm)
}


docs <- c("the first document contains words", "the second document is also made of words", "the third document is words and a number 4")
dictionary <- listAllWords(docs)
dtm <- sparser(docs,dictionary)

如果有什么不同,我将在 Mac OSX 的 R Studio 中运行它,64 位

4

3 回答 3

1

当然,您的问题的一部分是您实际上并没有存储整数,而是双精度数。笔记:

m <- mat.or.vec(100,32000)
m1 <- matrix(0L,100,32000)

> object.size(m)
25600200 bytes
> object.size(m1)
12800200 bytes

请注意以下代码中缺少“L” mat.or.vec

> mat.or.vec
function (nr, nc) 
if (nc == 1L) numeric(nr) else matrix(0, nr, nc)
<bytecode: 0x1089984d8>
<environment: namespace:base>

我认为,您还需要显式分配1L,否则 R 将在第一次分配时将所有内容转换为双精度数。您可以通过简单地分配一个m1高于值 1 的值并重新检查对象大小来验证这一点。

我可能还应该提到storage.mode可以帮助您验证您正在使用整数的函数。

于 2013-11-15T02:33:17.663 回答
0

如果您想经济地存储 0/1 值,我建议raw使用 type。

m8 <- matrix(0,100,32000)
m4 <- matrix(0L,100,32000)
m1 <- matrix(raw(1),100,32000)

raw类型每个值只占用 1 个字节:

> object.size(m8)
25600200 bytes
> object.size(m4)
12800200 bytes
> object.size(m1)
3200200 bytes

以下是如何使用它:

> m1[2,2] = as.raw(1)
> m1[2,2]
[1] 01
> as.integer(m1[2,2])
[1] 1
于 2013-11-15T04:39:36.330 回答
0

如果您真的想经济实惠,请查看ffbit包。

于 2013-11-15T04:51:39.837 回答