在 R 中使用大型文本文件来创建 n 元语法



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

  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")

在头疼之后,我自己解决了这个问题,以一种非常蛮力的方式,我有点尴尬,但无论如何我都会展示出来! 我相信有更优雅和有效的方法(请随时教育我)我只需要处理一次文本,所以我想不优雅的解决方案并不重要。

我转换为"tm"包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      }
                  }
                }

最新更新