Я працюю над проектом, де хочу отримати деяку інформацію про зміст серії відкритих нарисів. У цьому конкретному проекті 148 осіб написали нариси про гіпотетичну студентську організацію як частину більшого експерименту. Хоча в моїй галузі (соціальна психологія) типовим способом аналізу цих даних було б кодування есе вручну, я б хотів це зробити кількісно, оскільки ручне кодування є трудомістким і трохи надто суб'єктивним для мого смак.
Під час моїх досліджень щодо кількісного аналізу даних про вільну відповідь я натрапив на підхід під назвою моделювання тем (або Латентне розподілення Діріхле, або LDA). Тематичне моделювання містить суттєві подання ваших даних (матриця термінового документа) та використовує інформацію про слово співзвуччя для вилучення прихованих тем даних. Цей підхід здається ідеальним для мого застосування.
На жаль, коли я застосував моделювання тем до своїх даних, я виявив дві проблеми:
- Теми, розкриті моделюванням тем, часом важко інтерпретувати
- Коли я повторно запускаю свої тематичні моделі з іншим випадковим насінням, схоже, що теми різко змінюються
Питання 2, зокрема, стосується мене. Тому у мене є два пов'язані питання:
- Чи можу я щось зробити в процедурі LDA, щоб оптимізувати процедуру, що відповідає моїй моделі, для інтерпретації та стабільності? Особисто мене не так цікавить пошук моделі з найменшою недоумінністю та / або найкращою підходящою моделлю - я головним чином хочу скористатися цією процедурою, щоб допомогти мені зрозуміти та охарактеризувати те, що написали учасники цього дослідження у своїх рефератах. Однак я точно не хочу, щоб мої результати були артефактом випадкового насіння!
- Зв'язане з вищезазначеним питанням: Чи існують якісь стандарти щодо того, скільки даних вам потрібно, щоб зробити LDA? Більшість робіт, які я бачив, що використовували цей метод, аналізують великі корпорації (наприклад, архів усіх наукових праць за останні 20 років), але, оскільки я використовую експериментальні дані, мій корпус документів значно менший.
Я відправив дані есе тут для тих , хто хоче отримати свої брудні руки, і я вставив код R я використовую нижче.
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))
Редагувати:
Я спробував змінити, nstart
як запропонував Флоундер у коментарях. На жаль, як показано нижче, навіть встановлення nstart
до 1000 призводить до тем, які різко різняться від випадкового насіння до випадкового насіння. Ще раз наголошу, єдине, що я змінюю в оцінці двох моделей, наведених нижче, - це випадкове насіння, яке використовується для початку оцінки моделі, і все ж такі теми, схоже, зовсім не узгоджуються на цих двох етапах.
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
і перегляну веб-сайт курсу, щоб побачити, чи хтось із них дає щось корисне. (До речі, якщо ви вставите свої коментарі у відповідь, я проголосую за неї. Я хотів би побачити, чи є ще хтось хтось, перш ніж я щось прийму, але я вважаю, що ваших коментарів більш ніж достатньо, щоб вважати відповіддю).
LDA
функції вtopicmodels
пакеті. Зокрема, ви можете спробувати зробитиnstart
більше. Це гарантовано зробить ваші результати стабільнішими, оскільки функція LDA буде просто повторюватися з різними випадковими насінням, а потім повертати найкращий результат. На жаль, збільшенняnstart
до, скажімо, 1000 змусить алгоритм виконати в 1000 разів більше роботи (продовження)