Estoy trabajando en un proyecto en el que quiero extraer información sobre el contenido de una serie de ensayos abiertos. En este proyecto concreto, 148 personas escribieron ensayos sobre una hipotética organización estudiantil como parte de un experimento más amplio. Aunque en mi campo (la psicología social), la forma típica de analizar estos datos sería codificar los ensayos a mano, me gustaría hacerlo de forma cuantitativa, ya que la codificación a mano requiere mucho trabajo y es demasiado subjetiva para mi gusto.
Durante mis investigaciones sobre las formas de analizar cuantitativamente los datos de respuesta libre, me topé con un enfoque llamado modelización temática (o Latent Dirichlet Allocation, o LDA). El modelado de temas toma una representación de los datos en forma de bolsa de palabras (una matriz término-documento) y utiliza información sobre las co-ocurrencias de palabras para extraer los temas latentes de los datos. Este enfoque parece perfecto para mi aplicación.
Por desgracia, cuando he aplicado el modelado temático a mis datos, he descubierto dos problemas:
- Los temas descubiertos por la modelización temática son a veces difíciles de interpretar
- Cuando vuelvo a ejecutar mis modelos temáticos con una semilla aleatoria diferente, los temas parecen cambiar drásticamente.
La cuestión 2 en particular me preocupa. Por lo tanto, tengo dos preguntas relacionadas:
- ¿Hay algo que pueda hacer en el procedimiento LDA para optimizar mi procedimiento de ajuste del modelo en cuanto a interpretabilidad y estabilidad? Personalmente, no me importa tanto encontrar el modelo con la menor perplejidad y/o el mejor ajuste del modelo -- principalmente quiero usar este procedimiento para ayudarme a entender y caracterizar lo que los participantes en este estudio escribieron en sus ensayos. Sin embargo, ¡no quiero que mis resultados sean un artefacto de la semilla aleatoria!
- En relación con la pregunta anterior, ¿existen normas sobre la cantidad de datos que se necesitan para realizar un LDA? La mayoría de los trabajos que he visto que han utilizado este método analizan corpus grandes (por ejemplo, un archivo de todos los artículos de Science de los últimos 20 años), pero, como yo estoy utilizando datos experimentales, mi corpus de documentos es mucho más pequeño.
He publicado los datos del ensayo aquí para cualquiera que quiera ensuciarse las manos, y a continuación he pegado el código R que estoy utilizando.
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))
Edita:
He intentado modificar nstart
como sugiere Flounderer en los comentarios. Por desgracia, como se muestra a continuación, incluso la configuración de nstart
a 1000 resulta en temas que varían bastante de semilla aleatoria a semilla aleatoria. Sólo para enfatizar de nuevo, lo único que estoy cambiando en la estimación de los dos modelos a continuación es la semilla aleatoria utilizada para iniciar la estimación del modelo, y sin embargo, los temas no parecen ser en absoluto coherente en estas dos carreras.
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"