问题 在R中查找ngrams并在语料库中比较ngrams


我正在开始使用R中的tm软件包,所以请耐心等待,并为大文本墙做道歉。我创造了一个相当大的社会主义/共产主义宣传语料库,并希望提取新创造的政治术语(多个词,例如“斗争 - 批评 - 转型运动”)。

这是一个两步的问题,一个关于我的代码到目前为止,一个关于我应该如何继续。

步骤1: 为此,我想首先确定一些常见的ngram。但是我很早就陷入了困境。这是我一直在做的事情:

library(tm)
library(RWeka)

a  <-Corpus(DirSource("/mycorpora/1965"), readerControl = list(language="lat")) # that dir is full of txt files
summary(a)  
a <- tm_map(a, removeNumbers)
a <- tm_map(a, removePunctuation)
a <- tm_map(a , stripWhitespace)
a <- tm_map(a, tolower)
a <- tm_map(a, removeWords, stopwords("english")) 
a <- tm_map(a, stemDocument, language = "english") 
# everything works fine so far, so I start playing around with what I have
adtm <-DocumentTermMatrix(a) 
adtm <- removeSparseTerms(adtm, 0.75)

inspect(adtm) 

findFreqTerms(adtm, lowfreq=10) # find terms with a frequency higher than 10

findAssocs(adtm, "usa",.5) # just looking for some associations  
findAssocs(adtm, "china",.5)

# ... and so on, and so forth, all of this works fine

我加载到R中的语料库可以很好地处理我投入的大多数函数。从我的语料库创建TDM,找到频繁的单词,关联,创建单词云等等,我没有遇到任何问题。但是当我尝试使用中提到的方法来识别ngrams时 常见问题,我显然在使用tdm构造函数时犯了一些错误:

# Trigram

TrigramTokenizer <- function(x) NGramTokenizer(x, 
                                Weka_control(min = 3, max = 3))

tdm <- TermDocumentMatrix(a, control = list(tokenize = TrigramTokenizer))

inspect(tdm)

我收到此错误消息:

Error in rep(seq_along(x), sapply(tflist, length)) : 
invalid 'times' argument
In addition: Warning message:
In is.na(x) : is.na() applied to non-(list or vector) of type 'NULL'

有任何想法吗? “a”不是正确的类/对象吗?我很困惑。我认为这里有一个根本性的错误,但我没有看到它。 :(

第2步: 然后,当我将语料库与其他语料库进行比较时,我想确定明显过多的ngrams。例如,我可以将我的语料库与大型标准英语语料库进行比较。或者我创建可以相互比较的子集(例如苏联与中国共产党的术语)。你对我这样做有什么建议吗?我应该研究哪些脚本/函数?只是一些想法或指针会很棒。

谢谢你的耐心!


12441
2017-10-27 06:08


起源

我有同样的错误,对我来说,当我在Weka控制中设置与max不同的最小值时工作...不知道这是否适合你.... - holzben
谢谢你的建议!但是,对我来说不起作用。更改最小/最大值时,错误消息保持不变。 - Markus D
以防万一人们发现这个或者感兴趣:我实际上并没有解决第一个问题,但确实设法通过使用类似的功能来解决它 RTextTools 包: matrix <- create_matrix(corpus,ngramLength=3) - Markus D
您可以共享一些数据(可能在免费的临时文件托管站点上),这将有助于重现问题并找到解决方案。 - Ben
只需将可用内核数量设置为1: options(mc.cores=1) - marbel


答案:


我无法重现您的问题,您使用的是最新版本的R,tm,RWeka等吗?

require(tm)
a <- Corpus(DirSource("C:\\Downloads\\Only1965\\Only1965"))
summary(a)  
a <- tm_map(a, removeNumbers)
a <- tm_map(a, removePunctuation)
a <- tm_map(a , stripWhitespace)
a <- tm_map(a, tolower)
a <- tm_map(a, removeWords, stopwords("english")) 
# a <- tm_map(a, stemDocument, language = "english") 
# I also got it to work with stemming, but it takes so long...
adtm <-DocumentTermMatrix(a) 
adtm <- removeSparseTerms(adtm, 0.75)

inspect(adtm) 

findFreqTerms(adtm, lowfreq=10) # find terms with a frequency higher than 10
findAssocs(adtm, "usa",.5) # just looking for some associations  
findAssocs(adtm, "china",.5)

# Trigrams
require(RWeka)
TrigramTokenizer <- function(x) NGramTokenizer(x, Weka_control(min = 3, max = 3))
tdm <- TermDocumentMatrix(a, control = list(tokenize = TrigramTokenizer))
tdm <- removeSparseTerms(tdm, 0.75)
inspect(tdm[1:5,1:5])

这就是我得到的

A term-document matrix (5 terms, 5 documents)

Non-/sparse entries: 11/14
Sparsity           : 56%
Maximal term length: 28 
Weighting          : term frequency (tf)

                                   Docs
Terms                               PR1965-01.txt PR1965-02.txt PR1965-03.txt
  †chinese press                              0             0             0
  †renmin ribao                               0             1             1
  — renmin ribao                              2             5             2
  “ chinese people                            0             0             0
  “renmin ribaoâ€\u009d editorial             0             1             0
  etc. 

关于你的第二步,这里有一些指向有用的开头:

http://quantifyingmemory.blogspot.com/2013/02/mapping-significant-textual-differences.html http://tedunderwood.com/2012/08/14/where-to-start-with-text-mining/ 这是他的代码 https://dl.dropboxusercontent.com/u/4713959/Neuchatel/NassrProgram.R


7
2017-10-31 06:44



再次感谢你,本。我检查了我的R,RWeka和tm版本,一切似乎都是最新的。之前显然已经讨论过这个错误(stackoverflow.com/questions/17703553并且你已经权衡了它可能与Java安装有关。我尝试在Windows机器上运行代码,一切顺利,所以我猜这是问题所在。至于第2步,Ted Underwood的Nassr脚本似乎做了我正在寻找的东西,只有用词而不是ngram。我会尝试破译它并从中学习!谢谢! - Markus D
别担心。是的,Java ......我记得的一切都是它引起很多挫折!很高兴听到你有一些选择来克服这个障碍。想知道你的n-gram过度表达分析是如何进行的,当你有一些代码工作时,请发布另一个问题。 - Ben
这解决了我: options(mc.cores=1) - marbel


关于 步骤1,Brian.keng在这里给出了一个单线解决方案 https://stackoverflow.com/a/20251039/3107920 这解决了Mac OSX上的这个问题 - 它似乎与并行化有关,而不是(在Mac上的java设置的小噩梦)。


2
2018-03-26 13:02





您可能希望显式访问这样的函数

BigramTokenizer  <- function(x) {
    RWeka::NGramTokenizer(x, RWeka::Weka_control(min = 2, max = 3))
}

myTdmBi.d <- TermDocumentMatrix(
    myCorpus.d,
    control = list(tokenize = BigramTokenizer, weighting = weightTfIdf)
)

此外,其他一些随机出现的事情。

myCorpus.d <- tm_map(myCorpus.d, tolower)  # This does not work anymore 

试试这个

 myCorpus.d <- tm_map(myCorpus.d, content_transformer(tolower))  # Make lowercase

在RTextTools包中,

create_matrix(as.vector(C $ V2),ngramLength = 3)#ngramLength抛出错误信息。


1
2017-08-22 19:13





继Ben的回答 - 我也无法重现这一点,但在过去,我遇到了plyr包和冲突的依赖关系。 在我的情况下 Hmisc和ddply之间存在冲突。您可以尝试在违规代码行之前添加此行:

tryCatch(detach("package:Hmisc"), error = function(e) NULL)

如果这完全符合您的问题,请道歉!


0
2017-11-23 20:02