我有一个包含 600 万条消息的 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 在每一行:
ls()
[1] "sampletrainDT" "wordStem2"
的每一行sampletrainDT
是一条消息,主列是Body
。其他包含元数据,如 docid 等。
当我只使用数据的一个子集(10%)时,它运行得非常快(10 分钟),但如果我使用完整的数据集,它甚至不会完成,因为我在这条线上用完了 RAM sampletrainDT[, Body := gsub("<(.|\n)*?>", " ", Body)] # remove HTML tags
。在两行之间运行 gc() 似乎并没有改善这种情况。
我花了几天时间在谷歌上搜索一个解决方案,但我还没有找到一个好的解决方案,所以我很想听听其他在这方面有很多经验的人的意见。以下是我正在考虑的一些选项:
- ff 或 bigmemory - 难以使用且不适合文本
- 数据库
- 一次读取块,处理并附加到文件(更适合 Python?)
- 来自 tm 库的 PCorpus
- Map-reduce - 在本地完成,但希望以内存友好的方式
- R只是不是这个工具吗?
我想让它在单台机器(16 GB 笔记本电脑)上运行,而不是在 EC2 上使用大型机器。如果处理得当,6GB 的数据似乎并非不可逾越!