Stabilité des sujets dans les modèles de sujets

23

Je travaille sur un projet où je souhaite extraire des informations sur le contenu d'une série d'essais ouverts. Dans ce projet particulier, 148 personnes ont écrit des essais sur une organisation étudiante hypothétique dans le cadre d'une expérience plus vaste. Bien que dans mon domaine (psychologie sociale), la façon typique d'analyser ces données serait de coder les essais à la main, je voudrais le faire quantitativement, car le codage manuel est à la fois laborieux et un peu trop subjectif pour mon goût.

Au cours de mes recherches sur les moyens d'analyser quantitativement les données de réponses gratuites, je suis tombé sur une approche appelée modélisation de sujet (ou Latent Dirichlet Allocation, ou LDA). La modélisation de sujet prend une représentation en sac de mots de vos données (une matrice de document de terme) et utilise des informations sur les co-occurrences de mots pour extraire les sujets latents des données. Cette approche semble parfaite pour mon application.

Malheureusement, lorsque j'ai appliqué la modélisation de sujet à mes données, j'ai découvert deux problèmes:

  1. Les sujets découverts par la modélisation de sujets sont parfois difficiles à interpréter
  2. Lorsque je réexécute mes modèles de sujet avec une graine aléatoire différente, les sujets semblent changer radicalement

Le problème 2 me concerne particulièrement. Par conséquent, j'ai deux questions connexes:

  1. Y a-t-il quelque chose que je puisse faire dans la procédure LDA pour optimiser la procédure d'ajustement de mon modèle pour l'interprétabilité et la stabilité? Personnellement, je ne me soucie pas autant de trouver le modèle avec la perplexité la plus faible et / ou le meilleur ajustement du modèle - je veux principalement utiliser cette procédure pour m'aider à comprendre et à caractériser ce que les participants à cette étude ont écrit dans leurs essais. Cependant, je ne veux certainement pas que mes résultats soient un artefact de la graine aléatoire!
  2. En ce qui concerne la question ci-dessus, existe-t-il des normes concernant la quantité de données dont vous avez besoin pour effectuer un LDA? La plupart des articles que j'ai vus qui ont utilisé cette méthode analysent de grands corpus (par exemple, une archive de tous les articles scientifiques des 20 dernières années), mais, puisque j'utilise des données expérimentales, mon corpus de documents est beaucoup plus petit.

J'ai posté les données de l'essai ici pour quiconque veut se salir les mains, et j'ai collé le code R que j'utilise ci-dessous.

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

Modifier:

J'ai essayé de modifier nstartcomme suggéré par Flounderer dans les commentaires. Malheureusement, comme indiqué ci-dessous, même en définissant nstart1000 résultats, les sujets varient considérablement d'une graine aléatoire à une graine aléatoire. Juste pour souligner encore une fois, la seule chose que je change dans l'estimation des deux modèles ci-dessous est la graine aléatoire utilisée pour démarrer l'estimation du modèle, et pourtant les sujets ne semblent pas du tout cohérents dans ces deux séries.

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"
Patrick S. Forscher
la source
2
Merci de partager vos données! C'était très intéressant à regarder. Je n'ai pas une bonne réponse à vos questions, mais je veux suggérer certaines choses. Pour la question 1, vous pouvez essayer d'ajuster les paramètres de contrôle dans la LDAfonction du topicmodelspackage. En particulier, vous pouvez essayer d' nstartagrandir. Ceci est garanti pour rendre vos résultats plus stables, car la fonction LDA s'exécutera encore et encore avec différentes graines aléatoires, puis retournera le meilleur résultat. Malheureusement, augmenter nstartjusqu'à, disons, 1000 fera que l'algorithme fera 1000 fois plus de travail (suite)
Flounderer
1
ce sera donc beaucoup plus lent. Et rien ne garantit qu'il sera suffisamment stable . Re: les deux questions, il me semble que LDA est vraiment conçu pour classer les documents invisibles quand il y a trop de données à traiter pour un humain. Pour cela, c'est OK si l'algorithme VEM ne donne qu'une réponse "assez bonne" qui peut varier d'une exécution à l'autre. Mais pour vous, ce n'est pas souhaitable, et donc LDA pourrait ne pas être le meilleur choix. Il y a quelques excellentes alternatives dans les premières conférences du cours de Shalizi ici: stat.cmu.edu/~cshalizi/350 , par exemple, vous pouvez convertir chacune (suite)
Flounderer
2
essai à un vecteur sac de mots, puis faire un PCA sur les résultats, puis chercher des grappes. Quant à savoir si votre corpus est assez grand, pour être honnête, je ne serais pas surpris s'il est trop gros pour que VEM donne des résultats fiables. Je suis peut-être juste amer, mais j'ai passé énormément de temps à essayer de faire fonctionner cette méthode pour un autre modèle par des auteurs similaires, et c'était tout à fait incohérent d'une exécution à l'autre, même lorsque j'utilisais de petits exemples. Il n'y a pas beaucoup d'articles qui discutent du choix des points de départ pour des algorithmes comme celui-ci, pour autant que je sache.
Flounderer
Flounderer, merci beaucoup pour votre contribution! C'est un peu décevant pour moi d'entendre qu'il n'y a pas plus de lignes directrices sur la LDA spécifiquement, mais je suppose que cela vient avec le territoire d'une méthode non supervisée. Je vais essayer d'ajuster nstartet de regarder le site Web du cours pour voir si l'un ou l'autre produit quelque chose d'utile. (BTW, si vous insérez vos commentaires dans une réponse, je voterai. Je voudrais voir si quelqu'un d'autre a des conseils avant d'accepter quoi que ce soit, mais je pense que vos commentaires sont plus que suffisants pour compter comme une réponse).
Patrick S.Forscher
Je ressens votre douleur de grognement en sciences sociales, Patrick, mais je pense que votre approche est mauvaise au départ. Si vous souhaitez utiliser des tests statistiques, vous devrez demander à des humains d'en coder une partie pour obtenir les taux d'erreur de classification, l'avez-vous (personnellement) fait? Si c'est le cas, vous saurez quelles sont les fonctionnalités les plus importantes et vous pourrez concevoir / choisir un meilleur algorithme.
Indolering

Réponses:

6

Pour ma propre curiosité, j'ai appliqué un algorithme de clustering sur lequel j'ai travaillé à cet ensemble de données.

J'ai temporairement mis les résultats ici (choisissez l'ensemble de données d'essais).

Il semble que le problème ne soit pas les points de départ ou l'algorithme, mais les données. Vous pouvez `` raisonnablement '' (subjectivement, dans mon expérience limitée) obtenir de bons clusters même avec 147 instances tant qu'il y a des sujets / concepts / thèmes / clusters cachés (tout ce que vous souhaitez appeler).

Si les données n'ont pas de sujets bien séparés, quel que soit l'algorithme que vous utilisez, vous risquez de ne pas obtenir de bonnes réponses.

Siddharth Gopal
la source
@ Siddharth.Gopal Merci beaucoup pour la réponse! Il est vrai que je m'attendrais à un certain chevauchement dans les grappes étant donné que tous les participants décrivent une organisation étudiante hypothétique (que nous avons appelée "BadgerConnect"). Ainsi, contrairement à, par exemple, une application de la modélisation de sujets à des articles de Science, où certains sujets sont très différents d'un article à l'autre, les sujets sont tous un peu similaires. Cependant, il est vrai que certains des essais sont en faveur de BadgerConnect et certains sont écrits contre BadgerConnect.
Patrick
Il est également vrai que les essais varient considérablement dans le type d'arguments qu'ils présentent et comment les arguments sont présentés. J'aimerais saisir une partie de cette variabilité, si possible. Avez-vous une idée s'il est possible d'attraper certaines de ces distinctions (à tout le moins, la différence entre les essais en faveur et les essais contre ce programme étudiant hypothétique)? De plus, vos résultats de regroupement étaient-ils stables lorsque vous avez utilisé différentes graines aléatoires?
Patrick
1
1. Si vous êtes uniquement préoccupé par la stabilité de l'algorithme - essayez d'exécuter l'algorithme plusieurs fois et choisissez le modèle le plus probable.
Siddharth Gopal
1
(bien que la stabilité semble être un problème secondaire ici). 2. Compte tenu de votre description de ce que vous attendez en termes d'arguments et d'opinions, représenter les essais comme un sac de mots n'est pas une bonne idée dans ce contexte. En fait, le modèle de sujet n'est peut-être pas un bon outil pour cela. Je vous suggère de choisir quelques mots clés qui vous intéressent (comme la race, la nourriture, le dortoir, etc.) et d'essayer d'analyser le sentiment de la phrase dans laquelle le mot apparaît. Par exemple, regardez ici pour une démo.
Siddharth Gopal
1
Python a une excellente boîte à outils NLP appelée nltk. Vous voudrez peut-être jeter un œil à ce qu'il offre. En ce qui concerne tf-idf, «techniquement», l'entrée dans LDA ne devrait être que le nombre de mots car la distribution multinomiale n'est pas définie pour des nombres réels arbitraires.
Siddharth Gopal
10
  1. La notion de «sujets» dans les soi-disant «modèles de sujets» est trompeuse. Le modèle ne connaît pas ou n'est pas du tout conçu pour connaître des "sujets" sémantiquement cohérents. Les "sujets" ne sont que des distributions sur des jetons (mots). En d'autres termes, le modèle capture simplement la cooccurrence d'ordre élevé des termes. Que ces structures signifient quelque chose ou non n'est pas l'objectif du modèle.

  2. Le modèle "LDA" comprend deux parties (essentiellement tous les modèles graphiques): a) la définition du modèle et b) une implémentation d'un algorithme d'inférence pour déduire / évaluer les paramètres du modèle. La chose que vous avez mentionnée peut ou non être le problème du modèle "LDA" mais peut être un bug / erreur / mauvaise configuration de l'implémentation spécifique que vous avez utilisée (package R).

  3. Presque toutes les implémentations de "LDA" nécessitent une randomisation. Et par la nature des algorithmes d'inférence (par exemple, MCMC ou inférence variationnelle), vous obtiendrez des solutions minimales locales ou une distribution de nombreuses solutions. Donc, en bref, ce que vous avez observé est en quelque sorte attendu.

Suggestions pratiques:

  1. Essayez différents packages R: par exemple, ce package est réalisé par l'ancien étudiant diplômé de David Blei. Ou essayez même un autre environnement, comme celui-ci . Si vous obtenez des résultats similaires de tous ces packages stables, au moins, vous réduisez un peu le problème.

  2. Essayez de jouer un peu sans supprimer les mots vides. La raison en est que ces mots vides jouent un rôle important dans la connexion des significations sémantiques dans un si petit corpus (par exemple, une centaine d'articles). Aussi, essayez de ne pas filtrer les choses.

  3. Essayez de jouer un peu avec des hyper-paramètres, comme différents nombres de sujets.

Articles sur la cohérence des sujets:

  1. http://www.aclweb.org/anthology-new/D/D12/D12-1087.pdf

  2. http://people.cs.umass.edu/~wallach/publications/mimno11optimizing.pdf

Liangjie Hong
la source
Merci pour votre réponse. Je répondrai à vos commentaires un par un. (1) Je comprends que le modèle ne sait rien des sujets, mais votre affirmation selon laquelle les structures découvertes par les modèles de sujet (et que si ces structures signifient quelque chose ne sont pas le but de ces modèles) est directement contradictoire avec cet article de synthèse de David Blei, le créateur de modèles de sujet. Il me semble que le but des modèles de sujet est exactement d'aider à explorer / caractériser les données textuelles, ce qui est exactement ce que je veux faire dans ce projet.
Patrick S.Forscher
(2) Bien qu'il soit possible que mes résultats soient dus à un bug, je pense qu'il est plus probable qu'ils soient dus à une sorte d'erreur de ma part (et si cela semble être le cas, dites-le moi!). J'utilise le topicmodelspackage dans R, qui est essentiellement une interface R avec l'algorithme original implémenté par Blei et ses collègues.
Patrick S.Forscher
(3) Je sais que LDA nécessite une randomisation, donc je ne demande pas de résultats exacts d'une exécution à l'autre, mais je pense qu'il est raisonnable de s'attendre à des sujets similaires en utilisant différentes graines aléatoires (en effet, je pense que c'est une attente standard lorsque les gens utilisent des algorithmes basés sur la randomisation). Ce que je veux savoir, c'est comment parvenir à cette stabilité des résultats.
Patrick S.Forscher
@ PatrickS.Forscher À votre premier commentaire: Non, c'est contradictoire. Le nom «sujets» est ce que nous, en tant qu'êtres humains, mettons des étiquettes sur ces distributions de mots. Ces structures de clustering peuvent être liées ou non à des sujets lisibles dans le monde réel. Il existe un certain nombre d'articles pour introduire la cohérence dans les modèles de sujet afin d'atténuer le problème exact.
Liangjie Hong
@ PatrickS.Forscher À votre deuxième commentaire: Essayez une implémentation différente pour voir si vous obtenez des résultats similaires (résultats déraisonnables) ou non. Par exemple, UMASS Mallet.
Liangjie Hong