Sto lavorando a un progetto in cui desidero estrarre alcune informazioni sul contenuto di una serie di saggi aperti. In questo particolare progetto, 148 persone hanno scritto saggi su un'ipotetica organizzazione studentesca nell'ambito di un esperimento più ampio. Anche se nel mio campo (psicologia sociale), il modo tipico di analizzare questi dati sarebbe codificare i saggi a mano, mi piacerebbe farlo quantitativamente, poiché la codifica manuale è sia ad alta intensità di lavoro che un po 'troppo soggettiva per il mio gusto.
Durante le mie indagini sui modi per analizzare quantitativamente i dati di risposta libera, mi sono imbattuto in un approccio chiamato modellazione di argomenti (o Latent Dirichlet Allocation o LDA). La modellazione degli argomenti prende una rappresentazione bag-of-word dei tuoi dati (una matrice di documenti termici) e utilizza le informazioni sulle ricorrenze di parole per estrarre gli argomenti latenti dei dati. Questo approccio sembra perfetto per la mia applicazione.
Sfortunatamente, quando ho applicato la modellazione degli argomenti ai miei dati, ho scoperto due problemi:
- Gli argomenti scoperti dalla modellazione degli argomenti sono talvolta difficili da interpretare
- Quando rieseguo i miei modelli di argomento con un seme casuale diverso, gli argomenti sembrano cambiare radicalmente
Il numero 2 in particolare mi riguarda. Pertanto, ho due domande correlate:
- C'è qualcosa che posso fare nella procedura LDA per ottimizzare la mia procedura di adattamento del modello per interpretabilità e stabilità? Personalmente, non mi interessa molto trovare il modello con la minima perplessità e / o la migliore adattabilità al modello - Voglio principalmente utilizzare questa procedura per aiutarmi a capire e caratterizzare ciò che i partecipanti a questo studio hanno scritto nei loro saggi. Tuttavia, certamente non voglio che i miei risultati siano un artefatto del seme casuale!
- In relazione alla domanda di cui sopra, esistono degli standard per la quantità di dati necessari per eseguire una LDA? La maggior parte degli articoli che ho visto che hanno utilizzato questo metodo analizzano grandi corpora (ad esempio, un archivio di tutti gli articoli scientifici degli ultimi 20 anni), ma, poiché sto usando dati sperimentali, il mio corpus di documenti è molto più piccolo.
Ho pubblicato i dati del saggio qui per chiunque voglia sporcarsi le mani e ho incollato il codice R che sto usando di seguito.
require(tm)
require(topicmodels)
# Create a corpus from the essay
c <- Corpus(DataframeSource(essays))
inspect(c)
# Remove punctuation and put the words in lower case
c <- tm_map(c, removePunctuation)
c <- tm_map(c, tolower)
# Create a DocumentTermMatrix. The stopwords are the LIWC function word categories
# I have a copy of the LIWC dictionary, but if you want to do a similar analysis,
# use the default stop words in tm
dtm <- DocumentTermMatrix(c, control = list(stopwords =
c(dict$funct, dict$pronoun, dict$ppron, dict$i, dict$we, dict$you, dict$shehe,
dict$they, dict$inpers, dict$article, dict$aux)))
# Term frequency inverse-document frequency to select the desired words
term_tfidf <- tapply(dtm$v/rowSums(as.matrix(dtm))[dtm$i], dtm$j, mean) * log2(nDocs(dtm)/colSums(as.matrix(dtm)))
summary(term_tfidf)
dtm <- dtm[, term_tfidf >= 0.04]
lda <- LDA(dtm, k = 5, seed = 532)
perplexity(lda)
(terms <- terms(lda, 10))
(topics <- topics(lda))
Modificare:
Ho provato a modificare nstart
come suggerito da Flounderer nei commenti. Sfortunatamente, come mostrato di seguito, anche l'impostazione nstart
su 1000 comporta argomenti che variano in modo abbastanza drammatico da seme casuale a seme casuale. Solo per sottolineare ancora una volta, l'unica cosa che sto cambiando nella stima dei due modelli seguenti è il seme casuale usato per iniziare la stima del modello, eppure gli argomenti non sembrano essere coerenti in queste due serie.
lda <- LDA(dtm, k = 5, seed = 535, control = list(nstart = 1000))
(terms <- terms(lda, 10))
Topic 1 Topic 2 Topic 3 Topic 4 Topic 5
[1,] "international" "ethnicity" "free" "credit" "kind"
[2,] "communicate" "true" "team" "mandatory" "bridge"
[3,] "gain" "asians" "cooperate" "music" "close"
[4,] "use" "hand" "order" "seen" "deal"
[5,] "big" "hold" "play" "barrier" "designed"
[6,] "communication" "effective" "big" "stereotypes" "effort"
[7,] "america" "emphasis" "beginning" "asians" "implemented"
[8,] "chinese" "halls" "china" "fantastic" "websites"
[9,] "ethnicity" "minorities" "difference" "focusing" "planned"
[10,] "networks" "population" "easier" "force" "body"
lda <- LDA(dtm, k = 5, seed = 536, control = list(nstart = 1000))
(terms <- terms(lda, 10))
Topic 1 Topic 2 Topic 3 Topic 4 Topic 5
[1,] "kind" "international" "issue" "willing" "play"
[2,] "easier" "ethnicity" "close" "use" "trying"
[3,] "gain" "communication" "currently" "hand" "unity"
[4,] "websites" "communicate" "implemented" "networks" "decision"
[5,] "credit" "bridge" "particularly" "stereotypes" "gap"
[6,] "effort" "america" "credit" "communicate" "normally"
[7,] "barriers" "connection" "fulfill" "came" "asians"
[8,] "effects" "kind" "grew" "asians" "created"
[9,] "established" "order" "perspectives" "big" "effective"
[10,] "strangers" "skills" "big" "budget" "prejudice"
nstart
e guardare il sito web del corso per vedere se uno di questi produce qualcosa di utile. (A proposito, se inserisci i tuoi commenti in una risposta, lo voterò. Vorrei vedere se qualcun altro ha dei consigli prima di accettare qualcosa, ma penso che i tuoi commenti siano più che sufficienti per essere considerati come una risposta).
LDA
funzione neltopicmodels
pacchetto. In particolare, potresti provare anstart
ingrandirlo. Questo è garantito per rendere i tuoi risultati più stabili, perché la funzione LDA continuerà a funzionare ripetutamente con diversi semi casuali e quindi restituirà il miglior risultato. Sfortunatamente, aumentandonstart
, diciamo, 1000 farà lavorare l'algoritmo 1000 volte di più (proseguendo)