web-dev-qa-db-fra.com

Recherche de ngrammes dans R et comparaison de ngrammes entre corpus

Je commence à utiliser le paquet tm dans R, alors je vous prie de garder avec moi mes excuses pour le grand vieux mur de texte. J'ai créé un corpus assez large de propagande socialiste/communiste et voudrais extraire des termes politiques nouvellement inventés (plusieurs mots, par exemple "mouvement de lutte-critique-transformation"). 

Il s’agit d’une question en deux étapes, l’une concernant mon code jusqu’à présent et l’autre sur la façon dont je devrais continuer.

Étape 1: Pour ce faire, je voulais d'abord identifier quelques ngrammes communs. Mais je suis coincé très tôt. Voici ce que j'ai fait: 

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

Le corpus que je charge dans R fonctionne bien avec la plupart des fonctions que je lui lance. Je n'ai eu aucun problème à créer des TDM à partir de mon corpus, à trouver des mots fréquents, des associations, à créer des nuages ​​de mots, etc. Mais lorsque j'essaie d'utiliser des ngrammes d'identification en utilisant l'approche décrite dans le tm FAQ , je fais apparemment une erreur avec le constructeur tdm:

# Trigram

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

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

inspect(tdm)

Je reçois ce message d'erreur:

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'

Des idées? Est-ce que "a" n'est pas la bonne classe/objet? Je suis confus. Je suppose qu'il y a une erreur fondamentale ici, mais je ne la vois pas. :(

Étape 2: Je voudrais ensuite identifier les ngrams significativement surreprésentés lorsque je compare le corpus à d’autres corpus. Par exemple, je pourrais comparer mon corpus à un grand corpus anglais standard. Ou je crée des sous-ensembles que je peux comparer les uns aux autres (par exemple, la terminologie soviétique par rapport à une terminologie communiste chinoise). Avez-vous des suggestions sur la manière de procéder? Des scripts/fonctions que je devrais examiner? Quelques idées ou indications seraient géniales.

Merci pour votre patience!

11
Markus D

Je ne pourrais pas reproduire votre problème, utilisez-vous les dernières versions de R, tm, RWeka, etc.?

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

Et voici ce que je reçois

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. 

En ce qui concerne votre deuxième étape, voici quelques indications pour des débuts utiles:

http://quantifyingmemory.blogspot.com/2013/02/mapping-significant-textual-differences.htmlhttp://tedunderwood.com/2012/08/14/where- to-start-with-text-mining/ et voici son code https://dl.dropboxusercontent.com/u/4713959/Neuchatel/NassrProgram.R

7
Ben

À propos de Étape 1 , Brian.keng donne ici une solution de contournement en une ligne/ https://stackoverflow.com/a/20251039/3107920 qui semble avoir un lien avec la parallélisation plutôt que (le cauchemar mineur qui est) la configuration de Java sur mac.

2
cenau

Vous voudrez peut-être accéder explicitement aux fonctions comme ceci 

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

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

En outre, certaines autres choses qui ont été soulevées au hasard.

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

Essayez ceci à la place 

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

Dans le paquet RTextTools, 

create_matrix (as.vector (C $ V2), ngramLength = 3) # ngramLength émet un message d'erreur. 

1
Ashish M

Suite à la réponse de Ben, je ne pouvais pas reproduire cela non plus, mais j’ai eu des problèmes avec le paquet plyr et les dépendances conflictuelles. Dans mon cas il y avait un conflit entre Hmisc et ddply. Vous pouvez essayer d'ajouter cette ligne juste avant la ligne de code incriminée:

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

Toutes mes excuses si cela est complètement lié à votre problème!

0
Rolf Fredheim