Tôi đang làm việc trong một dự án mà tôi muốn trích xuất một số thông tin về nội dung của một loạt các bài tiểu luận mở. Trong dự án cụ thể này, 148 người đã viết bài luận về một tổ chức sinh viên giả định như một phần của một thí nghiệm lớn hơn. Mặc dù trong lĩnh vực của tôi (tâm lý học xã hội), cách điển hình để phân tích các dữ liệu này là viết mã các bài tiểu luận bằng tay, tôi muốn làm điều này một cách định lượng, vì mã hóa bằng tay vừa tốn nhiều công sức và hơi chủ quan đối với tôi nếm thử.
Trong quá trình điều tra về các cách phân tích định lượng dữ liệu phản hồi miễn phí, tôi tình cờ tìm thấy một phương pháp được gọi là mô hình hóa chủ đề (hoặc Phân bổ Dirichlet tiềm ẩn, hoặc LDA). Mô hình chủ đề lấy một đại diện bao gồm các từ của dữ liệu của bạn (ma trận tài liệu thuật ngữ) và sử dụng thông tin về các lần xuất hiện từ để trích xuất các chủ đề tiềm ẩn của dữ liệu. Cách tiếp cận này có vẻ hoàn hảo cho ứng dụng của tôi.
Thật không may, khi tôi áp dụng mô hình chủ đề cho dữ liệu của mình, tôi đã phát hiện ra hai vấn đề:
- Các chủ đề được phát hiện bởi mô hình chủ đề đôi khi rất khó để giải thích
- Khi tôi chạy lại các mô hình chủ đề của mình với một hạt giống ngẫu nhiên khác, các chủ đề dường như thay đổi đáng kể
Vấn đề 2 đặc biệt quan tâm đến tôi. Vì vậy, tôi có hai câu hỏi liên quan:
- Có bất cứ điều gì tôi có thể làm trong thủ tục LDA để tối ưu hóa quy trình phù hợp với mô hình của tôi về tính dễ hiểu và ổn định không? Cá nhân, tôi không quan tâm nhiều đến việc tìm ra mô hình với mức độ lúng túng thấp nhất và / hoặc mô hình phù hợp nhất - Tôi chủ yếu muốn sử dụng quy trình này để giúp tôi hiểu và mô tả những gì những người tham gia nghiên cứu này đã viết trong bài luận của họ. Tuy nhiên, tôi chắc chắn không muốn kết quả của mình là một tạo tác của hạt giống ngẫu nhiên!
- Liên quan đến câu hỏi trên, có tiêu chuẩn nào cho số lượng dữ liệu bạn cần để thực hiện LDA không? Hầu hết các bài báo tôi đã thấy đã sử dụng phương pháp này để phân tích khối lượng lớn (ví dụ: một kho lưu trữ tất cả các bài báo Khoa học từ 20 năm qua), nhưng, vì tôi đang sử dụng dữ liệu thực nghiệm, nên các tài liệu của tôi nhỏ hơn nhiều.
Tôi đã đăng dữ liệu bài luận ở đây cho bất kỳ ai muốn làm bẩn tay mình và tôi đã dán mã R tôi đang sử dụng bên dưới.
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))
Chỉnh sửa:
Tôi đã cố gắng sửa đổi nstart
theo đề xuất của Flounderer trong các bình luận. Thật không may, như được hiển thị bên dưới, thậm chí thiết lập nstart
tới 1000 kết quả trong các chủ đề thay đổi khá đột ngột từ hạt giống ngẫu nhiên sang hạt giống ngẫu nhiên. Chỉ cần nhấn mạnh một lần nữa, điều duy nhất tôi thay đổi trong ước tính của hai mô hình dưới đây là hạt giống ngẫu nhiên được sử dụng để bắt đầu ước lượng mô hình, và các chủ đề dường như không nhất quán trong hai lần chạy này.
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
và xem trang web của khóa học để xem liệu một trong hai điều đó có mang lại điều gì hữu ích không. (BTW, nếu bạn đưa ý kiến của mình vào câu trả lời, tôi sẽ bỏ phiếu. Tôi muốn xem có ai có lời khuyên trước khi tôi chấp nhận bất cứ điều gì không, nhưng tôi nghĩ rằng nhận xét của bạn là quá đủ để tính là một câu trả lời).
LDA
chức năng trongtopicmodels
gói. Đặc biệt, bạn có thể thử làm chonstart
lớn hơn. Điều này được đảm bảo để làm cho kết quả của bạn ổn định hơn, bởi vì hàm LDA sẽ chỉ chạy đi chạy lại với các hạt ngẫu nhiên khác nhau và sau đó trả về kết quả tốt nhất. Thật không may, tăngnstart
lên, giả sử, 1000 sẽ khiến thuật toán thực hiện công việc gấp 1000 lần (tiếp)