Bir dizi açık uçlu makalenin içeriği hakkında biraz bilgi edinmek istediğim bir proje üzerinde çalışıyorum. Bu özel projede 148 kişi, daha büyük bir deneyin parçası olarak varsayımsal bir öğrenci organizasyonu hakkında yazılar yazdı. Alanımda (sosyal psikoloji), bu verileri analiz etmenin tipik yolu, makaleleri elle kodlamak olsa da, bunu nicel olarak yapmak istiyorum, çünkü el kodlaması hem emek yoğun hem de benim için çok özneldir. damak zevki.
Serbest cevap verilerini nicel olarak analiz etmenin yolları hakkındaki araştırmalarım sırasında, konu modelleme (ya da Latent Dirichlet Allocation, veya LDA) adı verilen bir yaklaşıma rastladım . Konu modelleme, verilerinizin bir sözcük ifadesi temsilini (bir terim belgesi matrisi) alır ve verinin gizli konularını çıkarmak için eş-beraberlik kelimesi hakkındaki bilgileri kullanır. Bu yaklaşım başvurum için mükemmel görünüyor.
Maalesef verilerime konu modelleme uyguladığımda iki konu keşfettim:
- Konu modellemeyle ele geçen konuları yorumlamak bazen zor
- Konu modellerimi farklı bir rastgele tohumla tekrar çalıştırdığımda, konular çarpıcı biçimde değişiyor gibi görünüyor
Özellikle 2. konu beni ilgilendirmektedir. Bu nedenle, iki tane ilgili sorum var:
- Modelimi yorumlanabilirlik ve stabilite için uygun prosedürümü optimize etmek için LDA prosedüründe yapabileceğim bir şey var mı? Şahsen, en düşük şaşkınlığa ve / veya en iyi model uygunluğa sahip modeli bulmayı umursamıyorum - Bu çalışmanın katılımcılarının yazılarında yazdıklarını anlamama ve karakterize etmeme yardımcı olmak için çoğunlukla bu prosedürü kullanmak istiyorum. Ancak, sonuçlarımın kesinlikle rastgele tohumun bir eseri olmasını istemiyorum!
- Yukarıdaki soruya ilişkin olarak, bir LDA yapmak için ne kadar veriye ihtiyaç duyduğunuz konusunda standartlar var mı? Bu yöntemi kullanmış olduğum makalelerin çoğu büyük kurumları analiz ediyor (örneğin, son 20 yıldaki tüm Bilim makalelerinin bir arşivi), ancak deneysel veriler kullandığım için belgeler grubum çok daha küçük.
Ellerini kirletmek isteyen herkes için deneme verilerini buraya yazdım ve aşağıda kullandığım R kodunu yapıştırdım.
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))
Düzenle:
nstart
Yorumlarda Flounderer tarafından önerildiği şekilde değişiklik yapmayı denedim . Ne yazık ki, aşağıda gösterildiği gibi, nstart
rastgele tohumdan rastgele tohuma oldukça dramatik biçimde değişen konularda 1000 sonuçlara ayarlanması bile . Sadece tekrar vurgulamak gerekirse, aşağıdaki iki modelin tahmininde değiştirdiğim tek şey, model tahminine başlamak için kullanılan rastgele tohumdur ve yine de konular bu iki çalışmada tutarlı görünmüyor.
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
Bunlardan herhangi birinin işe yarayıp yaramadığını görmek için kurgu web sitesine bakmaya çalışacağım . (BTW, yorumlarınızı bir cevaba eklerseniz, oy kullanırım. Herhangi bir şeyi kabul etmeden önce başkalarının tavsiyesi olup olmadığını görmek isterim, ancak yorumlarınızın yanıt olarak kabul edilmekten daha fazlası olduğunu düşünüyorum.
LDA
fonksiyondaki kontrol parametrelerini ayarlamayı deneyebilirsiniztopicmodels
. Özellikle,nstart
daha büyük olmayı deneyebilirsiniz . Bu, sonuçlarınızı daha kararlı hale getirme garantilidir , çünkü LDA işlevi farklı rasgele tohumlarla tekrar tekrar tekrar çalışacak ve daha sonra en iyi sonucu verecektir. Ne yazıknstart
ki, 1000’in artması , algoritmanın 1000 kat daha fazla iş yapmasını sağlayacak (devam ediyor)