Поиск ngrams в R и сравнение ngrams через корпуса
Я начинаю с пакета tm в R, поэтому, пожалуйста, несите меня и приносите извинения за большую стену текста. Я создал довольно большой корпус социалистической/коммунистической пропаганды и хотел бы извлечь недавно придуманные политические термины (несколько слов, например, "борьба-критика-трансформация" ).
Это двухэтапный вопрос, один из которых касается моего кода до сих пор, и один вопрос о том, как я должен продолжать.
Шаг 1: Чтобы сделать это, я хотел сначала определить некоторые общие ngrams. Но я застрял очень рано. Вот что я делал:
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, используя подход, описанный в tm FAQ, я, по-видимому, ошибаюсь в конструкторе 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: Затем я хотел бы определить ngrams, которые значительно перепредставлены, когда я сравниваю корпус с другими корпусами. Например, я мог сравнить свой корпус с большим стандартным английским корпусом. Или я создаю подмножества, которые я могу сравнивать друг с другом (например, советская и китайская коммунистическая терминология). Есть ли у вас какие-либо предложения, как я должен это делать? Любые скрипты/функции, которые я должен изучить? Просто некоторые идеи или указатели были бы замечательными.
Спасибо за ваше терпение!
Ответы
Ответ 1
Я не мог воспроизвести вашу проблему, используете ли вы последние версии 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
Ответ 2
Что касается Шаг 1, Brian.keng дает обходное решение для одного лайнера здесь fooobar.com/questions/329137/..., которое решает эту проблему на Mac OSX - кажется быть связанными с параллелизацией, а не (малый кошмар, который есть) java setup на mac.
Ответ 3
Вы можете явно получить доступ к таким функциям
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 выдает сообщение об ошибке.
Ответ 4
В дополнение к ответу Бена - я тоже не смог воспроизвести это, но в прошлом у меня были проблемы с пакетом plyr и конфликтующими зависимостями. В моем случае произошел конфликт между Hmisc и ddply. Вы можете попробовать добавить эту строку непосредственно перед оскорбительной строкой кода:
tryCatch(detach("package:Hmisc"), error = function(e) NULL)
Извините, если это полностью касается вашей проблемы!