在R中处理大型文本文件

时间:2013-10-17 15:15:54

标签: r large-files text-processing tm

我有6GB的6GB数据集要处理 - 我的目标是为我的数据集创建一个文档术语矩阵,但我需要进行一些预处理(删除HTML标记,阻止,停止 - 首先删除单词等。

以下是我目前正在尝试做的所有事情:

library(data.table)
library(tm)

wordStem2 <- function(strings){
  sapply(lapply(strsplit(stripWhitespace(strings), " "), wordStem), function(x) paste(x, collapse=" "))
}

load("data/train.RData")
sampletrainDT <- as.data.table(train)
rm(train)
setkey(sampletrainDT, Id)

object.size(sampletrainDT) # 5,632,195,744 bytes

gc()
sampletrainDT[, Body := tolower(Body)]
object.size(sampletrainDT) # 5,631,997,712 bytes, but rsession usage is at 12 GB. gc doesn't help.
gc()
sampletrainDT[, Body := gsub("<(.|\n)*?>", " ", Body)] # remove HTML tags
sampletrainDT[, Body := gsub("\n", " ", Body)] # remove \n
sampletrainDT[, Body := removePunctuation(Body)]
sampletrainDT[, Body := removeNumbers(Body)]
sampletrainDT[, Body := removeWords(Body, stopwords("english"))]
sampletrainDT[, Body := stripWhitespace(Body)]
sampletrainDT[, Body := wordStem2(Body)]

各行:

ls()
[1] "sampletrainDT" "wordStem2"  

sampletrainDT的每一行都是一条消息,主列是Body。其他包含docid等元数据。

当我只处理一部分数据(10%)时,这种情况运行得非常快(10分钟),但如果我使用完整的数据集,它甚至都没有完成,因为我在这行上耗尽了RAM { {1}}。在行之间运行gc()似乎不会改善这种情况。

我花了几天时间用谷歌搜索解决方案,但我还没有找到一个好的解决方案,所以我很想听听那些在这方面有很多经验的人。以下是我正在考虑的一些选项:

  1. ff或bigmemory - 难以使用且不适合文字
  2. 数据库
  3. 一次读取块,处理并附加到文件(更适合Python?)
  4. 来自tm library的PCorpus
  5. Map-reduce - 在本地完成但希望以内存友好的方式完成
  6. R不是这个工具吗?
  7. 我想在一台机器(16 GB笔记本电脑)上运行,而不是在EC2上使用大型机器。如果做得好,6GB的数据似乎无法克服!

1 个答案:

答案 0 :(得分:1)

我不确定究竟发生了什么,但这里有一些有用的提示。首先,这是一个用于监视哪些对象占用内存的函数:

lsBySize<-function(k=20,envir=globalenv()){
  z <- sapply(ls(envir=envir), function(x) object.size(get(x)))
  ret<-sort(z,T)
  if(k>0)
    ret<-ret[1:min(k,length(ret))]

  as.matrix(ret)/10^6
}

随时运行gc()将告诉您当前正在使用多少内存。如果sum(lsBySize(length(ls)))gc()报告的内存量大致不相等,那么就会发生一些奇怪的事情。在这种情况下,请编辑OP以显示连续运行这两个命令的R会话的输出。另外,为了隔离这个问题,最好使用data.frames,至少目前是这样,因为data.tables的内部更加复杂和不透明。