Нахождение нграмм в R и сравнение нграмм по всем корпорациям

Я начинаю работать с пакетом tm в R, так что, пожалуйста, потерпите меня и приносим извинения за большую старую стену текста. Я создал довольно большой корпус социалистической / коммунистической пропаганды и хотел бы извлечь недавно придуманные политические термины (несколько слов, например, "движение-критика-трансформационное движение").

Это двухэтапный вопрос, один из которых касается моего кода на данный момент, а другой - о том, как мне действовать дальше.

Шаг 1: Чтобы сделать это, я хотел сначала определить некоторые общие нграммы. Но я застреваю очень рано. Вот что я делал:

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 из моего корпуса, поиском частых слов, ассоциаций, созданием облаков слов и так далее. Но когда я пытаюсь использовать идентифицирующие нграммы, используя подход, описанный в FAQ по tm, я, очевидно, допускаю некоторую ошибку с конструктором 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'

Есть идеи? Разве "а" не правильный класс / объект? Я не совсем понимаю. Я предполагаю, что здесь есть фундаментальная ошибка, но я ее не вижу.:(

Шаг 2: Затем я хотел бы идентифицировать нграммы, которые значительно перепредставлены, когда я сравниваю корпус с другими корпусами. Например, я мог бы сравнить мой корпус с большим стандартным английским корпусом. Или я создаю подмножества, которые я могу сравнивать друг с другом (например, советская или китайская коммунистическая терминология). У вас есть предложения, как мне поступить? Какие скрипты / функции мне следует изучить? Просто некоторые идеи или указатели были бы великолепны.

Спасибо тебе за твое терпение!

4 ответа

Я не смог воспроизвести вашу проблему, вы используете последние версии 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

Что касается шага 1, Brian.keng предлагает обходной путь здесь, /questions/19614611/bigrammyi-vmesto-otdelnyih-slov-v-matritse-termodokumentov-s-ispolzovaniem-r-i-rweka/19614624#19614624 который решает эту проблему на Mac OSX - скорее всего, это связано с распараллеливанием, а не с (небольшим кошмаром) Настройка Java на Mac.

Вы можете явно получить доступ к таким функциям

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 выдает сообщение об ошибке.

В дополнение к ответу Бена - я тоже не мог воспроизвести это, но в прошлом у меня были проблемы с пакетом plyr и конфликтующими зависимостями. В моем случае был конфликт между Hmisc и ddply. Вы можете попробовать добавить эту строку непосредственно перед ошибочной строкой кода:

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

Извиняюсь, если это полностью касается вашей проблемы!

Другие вопросы по тегам