私は、一連の自由記述式エッセイの内容に関する情報を抽出したいプロジェクトに取り組んでいます。この特定のプロジェクトでは、148人が、大規模な実験の一環として、仮想の学生組織についてのエッセイを書きました。私の分野(社会心理学)では、これらのデータを分析する典型的な方法はエッセイを手作業でコーディングすることですが、ハンドコーディングは労働集約的であり、私にとっては少し主観的であるため、これを定量的に行いたいと思います味。
無料の応答データを定量的に分析する方法についての調査中に、トピックモデリング(またはLatent Dirichlet Allocation、またはLDA)と呼ばれるアプローチを見つけました。トピックモデリングでは、データの単語の表現(用語ドキュメントマトリックス)を使用し、単語の共起に関する情報を使用して、データの潜在的なトピックを抽出します。このアプローチは私のアプリケーションに最適のようです。
残念ながら、トピックモデリングをデータに適用すると、2つの問題が見つかりました。
- トピックモデリングによって明らかにされたトピックは、解釈が難しい場合があります
- 別のランダムシードを使用してトピックモデルを再実行すると、トピックが劇的に変化するように見える
特に問題2は私に関係しています。したがって、2つの関連する質問があります。
- 解釈可能性と安定性のためにモデル適合手順を最適化するために、LDA手順でできることはありますか?個人的に、私は、最も低いパープレキシティおよび/または最高のモデル適合性を持つモデルを見つけることについてあまり気にしません-私は主にこの手順を使用して、この研究の参加者がエッセイで書いたものを理解し、特徴づけるのを助けたいです。ただし、結果がランダムシードのアーティファクトになりたくないのは確かです。
- 上記の質問に関連して、LDAを実行するために必要なデータ量の基準はありますか?この方法を使用した私が見たほとんどの論文は、大きなコーパスを分析します(たとえば、過去20年間のすべてのScience論文のアーカイブ)が、実験データを使用しているため、ドキュメントのコーパスははるかに小さくなります。
手を汚したい人のために、ここにエッセイデータを投稿しました。使用している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に設定しても、ランダムシードからランダムシードまで非常に劇的に変化するトピックになります。繰り返しますが、以下の2つのモデルの推定で変更しているのは、モデルの推定を開始するために使用されるランダムシードのみですが、これらの2つの実行でトピックはまったく一貫していないようです。
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
コースのWebサイトを調整して見て、どちらかが有用かどうかを確認します。(ところで、あなたがあなたのコメントを回答に挿入したら、私はそれを投票します。私が何かを受け入れる前に誰か他の人に助言があるかどうかを見たいと思いますが、あなたのコメントは答えとして数えるのに十分すぎると思います)。
LDA
、topicmodels
パッケージ内の関数の制御パラメーターを調整してみてください。特に、nstart
大きくすることができます。これにより、結果がより安定することが保証されます。LDA関数は、異なるランダムシードを使用して何度も繰り返し実行し、最適な結果を返すためです。残念ながら、増加しnstart
1000は、アルゴリズムが1000倍以上の作業(続き)を行うようになります、と言う、に