Я работаю над проектом, в котором я хочу извлечь некоторую информацию о содержании серии открытых эссе. В этом конкретном проекте 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
как предложено Flounderer в комментариях. К сожалению, как показано ниже, даже установка 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"
источник
LDA
функции изtopicmodels
пакета. В частности, вы можете попробовать сделатьnstart
больше. Это гарантированно сделает ваши результаты более стабильными, потому что функция LDA будет просто запускаться снова и снова с различными случайными начальными значениями, а затем возвращать лучший результат. К сожалению, увеличениеnstart
до, скажем, 1000 заставит алгоритм выполнять в 1000 раз больше работы (продолжение)nstart
и просмотреть веб-сайт курса, чтобы увидеть, принесет ли что-нибудь из этого что-нибудь полезное. (Кстати, если вы добавите свои комментарии в ответ, я проголосую за него. Я хотел бы узнать, есть ли у кого-нибудь еще совет, прежде чем я что-либо приму, но я думаю, что ваши комментарии более чем достаточны для того, чтобы считаться ответом).Ответы:
Для собственного любопытства я применил алгоритм кластеризации, над которым я работал, к этому набору данных.
Я временно выставил здесь результаты (выберите набор данных очерков).
Кажется, что проблема не в отправных точках или алгоритме, а в данных. Вы можете «разумно» (субъективно, в моем ограниченном опыте) получить хорошие кластеры даже с 147 экземплярами, если есть какие-то скрытые темы / концепции / темы / кластеры (как бы вы ни хотели назвать).
Если в данных нет разделенных тем, то независимо от того, какой алгоритм вы используете, вы можете не получить хороших ответов.
источник
Понятие «темы» в так называемых «моделях темы» вводит в заблуждение. Модель не знает или не предназначена для того, чтобы вообще знать семантически согласованные «темы». «Темы» - это просто распределение по токенам (словам). Другими словами, модель просто фиксирует одновременное появление терминов высокого порядка. Являются ли эти структуры что-то значимыми или нет, это не цель модели.
Модель «LDA» состоит из двух частей (по существу, всех графических моделей): а) определение модели и б) реализация алгоритма вывода для определения параметров модели / состояния. То, что вы упомянули, может быть или не быть проблемой модели "LDA", но может быть некоторой ошибкой / ошибкой / неправильной настройкой конкретной используемой вами реализации (пакет R).
Почти все реализации "LDA" требуют некоторой рандомизации. А по характеру алгоритмов вывода (например, MCMC или вариационного вывода) вы получите локальные минимальные решения или распределение многих решений. Короче говоря, то, что вы наблюдали, как-то ожидается.
Практические предложения:
Попробуйте разные пакеты R: Например, этот пакет сделан бывшим аспирантом Дэвида Блея. Или даже попробуйте другую среду, такую как эта . Если вы получите похожие результаты от всех этих стабильных пакетов, по крайней мере, вы немного уменьшите проблему.
Попробуйте немного поиграть, не удаляя стоп-слова. Смысл в том, что эти стоп-слова играют важную роль в соединении смысловых значений в таком маленьком корпусе (например, около 100 статей). Кроме того, постарайтесь не фильтровать вещи.
Попробуйте немного поиграть с гиперпараметрами, например, с разными номерами тем.
Статьи о тематических связях:
http://www.aclweb.org/anthology-new/D/D12/D12-1087.pdf
http://people.cs.umass.edu/~wallach/publications/mimno11optimizing.pdf
источник
topicmodels
пакет в R, который по сути является интерфейсом R к оригинальному алгоритму, реализованному Блеяем и его коллегами.