在R中查找ngram并比较不同语料库中的ngram

12

我正在学习如何使用R中的tm包,因此请耐心等待,对于这篇大段文字,我很抱歉。我已经创建了一个相当大的社会主义/共产主义宣传语料库,并希望提取新的政治术语(多个词,例如“斗争-批判-改造运动”)。

这是一个两步问题,一个涉及我的代码到目前为止,另一个涉及我接下来该怎么做。

第一步:为了实现这一点,我想首先识别一些常见的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、查找常用词、关联词、创建词云等方面的任何问题。但是,当我尝试使用在tm FAQ中概述的方法来识别ngram时,我似乎在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:然后,我想识别那些在与其他语料库比较时显着过表现的ngram。例如,我可以将我的语料库与一个大型标准英语语料库进行比较,或者我可以创建子集并将它们相互比较(例如苏联与中国共产党的术语)。您有任何建议如何完成此操作吗?我应该查找哪些脚本/函数?只是一些思路或指针就很好了。

感谢您的耐心!


我曾经遇到过同样的错误,当我在Weka控制面板中将最小值和最大值设置为不同的值时,问题得到了解决...不知道这对你是否可行... - holzben
谢谢您的建议!不过对我没用。当我更改最小/最大值时,错误信息仍然是相同的。 - Markus D
6
万一有人找到或者对此感兴趣:我实际上没有解决第一个问题,但是成功地通过使用RTextTools软件包提供的类似函数来绕过它:matrix <- create_matrix(corpus,ngramLength=3) - Markus D
谢谢。是的,我已经在这里上传了一个语料库样本:http://s000.tinyupload.com/index.php?file_id=46554569218218543610 - Markus D
1
只需将可用核心数设置为1:options(mc.cores=1) - marbel
显示剩余2条评论
4个回答

7

我无法重现你的问题,你正在使用最新版本的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|NassrProgram.R


再次感谢您,Ben。我已检查了我的R、RWeka和tm版本,一切似乎都是最新的。这个错误显然已经讨论过了(https://dev59.com/SmMm5IYBdhLWcg3wVdt5),你曾经提到它可能与Java安装有关。我尝试在Windows机器上运行代码,一切都很顺利,所以我猜那就是问题所在。至于第二步,Ted Underwood的Nassr脚本似乎可以做到我想要的事情,只不过是用单词而不是ngrams。我会尝试解密它并学习它!谢谢! - Markus D
没问题。是的,Java...我记得的就是它带来了很多挫败感!很高兴听到你有几个选项可以克服这个障碍。好奇你的n-gram过度表现分析如何进行,当你有一些可用的代码时,请发布另一个问题。 - Ben

2

关于第一步,Brian.keng在这里给出了一个简单的解决方法https://dev59.com/SmMm5IYBdhLWcg3wVdt5#20251039,可以在Mac OSX上解决这个问题-似乎与并行化有关,而不是(那个小噩梦)Mac上的Java设置。


1
你可能希望像这样显式地访问函数。
BigramTokenizer  <- function(x) {
    RWeka::NGramTokenizer(x, RWeka::Weka_control(min = 2, max = 3))
}

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

此文段为英语,意思是:“还有一些其他随机出现的事情。”其中包含HTML代码,不做解释。
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的值为3,会出现错误信息。

0

关于Ben的回答 - 我也无法重现这个问题,但过去我曾遇到过plyr包和冲突依赖项的问题。在我的情况下,Hmisc和ddply之间存在冲突。您可以尝试在有问题的代码行之前添加此行:

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

如果这与您的问题完全无关,我很抱歉!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接