使用R中的大型文本文件来创建n-gram

时间:2017-01-09 16:20:59

标签: r nlp

我正在尝试使用R编程环境中的“quanteda”软件包从大型(1GB)文本文件创建三元组和双字母组合。如果我尝试一次运行我的代码(如下所示),R就会挂起(在第3行 - myCorpus< -toLower(...))。我在小数据集< 1mb上成功使用了代码,所以我猜文件太大了。我可以看到我可能需要在“块”中加载文本,然后将结果的bigrams和trigrams频率组合起来。但我无法弄清楚如何以可管理的“块”加载和处理文本。任何关于解决这个问题的方法都会受到欢迎。我的代码粘贴在下面。对于改进我的代码的其他方法的任何建议也是受欢迎的。

  folder.dataset.english <- 'final/corpus'


myCorpus <- corpus(x=textfile(list.files(path = folder.dataset.english, pattern = "\\.txt$", full.names = TRUE, recursive = FALSE)))  # build the corpus

myCorpus<-toLower(myCorpus, keepAcronyms = TRUE)

#bigrams
bigrams<-dfm(myCorpus, ngrams = 2,verbose = TRUE, toLower = TRUE,
             removeNumbers = TRUE, removePunct = TRUE, removeSeparators = TRUE,removeTwitter = TRUE, stem = FALSE) 
bigrams_freq<-sort(colSums(bigrams),decreasing=T)
bigrams<-data.frame(names=names(bigrams_freq),freq=bigrams_freq,stringsAsFactors =FALSE)
bigrams$first<- sapply(strsplit(bigrams$names, "_"), "[[", 1)
bigrams$last<-  sapply(strsplit(bigrams$names, "_"), "[[", 2)
rownames(bigrams)<-NULL
bigrams.freq.freq<-table(bigrams$freq)
saveRDS(bigrams,"dictionaries/bigrams.rds")

#trigrams
trigrams<-dfm(myCorpus, ngrams = 3,verbose = TRUE, toLower = TRUE,
              removeNumbers = TRUE, removePunct = TRUE, removeSeparators = TRUE,
              removeTwitter = TRUE, stem = FALSE) 
trigrams_freq<-sort(colSums(trigrams),decreasing=T)
trigrams<-data.frame(names=names(trigrams_freq),freq=trigrams_freq,stringsAsFactors =FALSE)

trigrams$first<-paste(sapply(strsplit(trigrams$names, "_"), "[[", 1),sapply(strsplit(trigrams$names, "_"), "[[", 2),sep="_")
trigrams$last<-sapply(strsplit(trigrams$names, "_"), "[[", 3)
rownames(trigrams)<-NULL
saveRDS(trigrams,"dictionaries/trigrams.rds")

1 个答案:

答案 0 :(得分:0)

经过一番头痛之后,我有点以一种非常蛮力的方式解决了这个问题,我对此感到有些尴尬,但无论如何我都会表现出来!我相信有更优雅和有效的方法(请随时教我)我只需要处理一次这个文本,所以我觉得不优雅的解决方案并不重要。

我转换成了一个&#39;&#39;包V.Corpus对象,它由三个大文本文件组成,然后迭代通过三个文本文件并手动切片处理每个块的语料库一次。为了清楚理解,我在这里没有插入和检测上面给出的处理代码。我刚刚指出了我需要在哪里缝合。我现在需要添加一些代码来累积每个块的结果。

library(tm)

 folder.dataset.english <- 'final/corpus'
    corpus <- VCorpus(DirSource(directory=folder.dataset.english, encoding = "UTF-8",recursive=FALSE),
                      readerControl = list(language = "en"))
    chunk.size<-100000


    for(t in 1:3){
        l=1
        h=chunk.size
        stp=0
        corp.size<-length(corpus[[t]]$content)
          repeat{  
            if(stp==2)break
            corpus.chunk<-corpus[[t]]$content[l:h]
            l<-h+1
            h<-h+chunk.size
    ####Processing code in here


    #####Processing code ends here
            if(h>corp.size){
            h<-corp.size
            stp<-stp+1      }
                  }
                }