Тематическое моделирование: LDA, частота слов в каждой теме и Wordcloud

Вопрос: Как я могу вычислить и закодировать частоту слов в каждой теме? Моя цель — создать «Облако слов» из каждой темы.

P.S.> У меня нет проблем с wordcloud.

Из кода,

  burnin <- 4000  #We do not collect this.
  iter <- 4000
  thin <- 500
  seed <-list(2017,5,63,100001,765)
  nstart <- 5
  best <- TRUE
  #Number of topics: 
  k <- 4
  LDA_results <-LDA(DTM,k, method="Gibbs", control=list(nstart=nstart,
                           seed = seed, best=best, 
                           burnin = burnin, iter = iter, thin=thin))

Спасибо (я стараюсь сделать вопрос как можно более кратким, поэтому, если вам нужны дополнительные подробности, я могу добавить больше.)


person SChatcha    schedule 08.08.2017    source источник


Ответы (2)


Если вы хотите создать облако слов для каждой темы, вам нужны самые популярные термины для каждой темы, то есть наиболее вероятные слова, которые будут сгенерированы из каждой темы. Эта вероятность называется beta; это вероятность на тему на слово. Чем выше эта бета-вероятность, тем выше вероятность того, что это слово сгенерировано из этой темы.

Вы можете получить beta вероятности в аккуратном фрейме данных из вашей тематической модели LDA, используя tidy из tidytext. Давайте посмотрим на примерный набор данных и подберем модель, используя всего две темы.

library(tidyverse)
library(tidytext)
library(topicmodels)

data("AssociatedPress")
ap_lda <- LDA(AssociatedPress, k = 2, control = list(seed = 1234))

Теперь вы подходите под модель! Теперь мы можем получить вероятности.

ap_topics <- tidy(ap_lda, matrix = "beta")

ap_topics
#> # A tibble: 20,946 x 3
#>    topic       term         beta
#>    <int>      <chr>        <dbl>
#>  1     1      aaron 1.686917e-12
#>  2     2      aaron 3.895941e-05
#>  3     1    abandon 2.654910e-05
#>  4     2    abandon 3.990786e-05
#>  5     1  abandoned 1.390663e-04
#>  6     2  abandoned 5.876946e-05
#>  7     1 abandoning 2.454843e-33
#>  8     2 abandoning 2.337565e-05
#>  9     1     abbott 2.130484e-06
#> 10     2     abbott 2.968045e-05
#> # ... with 20,936 more rows

Они там все смешались. Давайте воспользуемся dplyr, чтобы получить наиболее вероятные термины для каждой из тем.

ap_top_terms <- ap_topics %>%
  group_by(topic) %>%
  top_n(200, beta) %>%
  ungroup() %>%
  arrange(topic, -beta)

Теперь вы можете использовать это, чтобы создать облако слов (с некоторым изменением формы). Вероятность beta — это то, что вы хотите соответствовать тому, насколько велики слова.

library(wordcloud)
library(reshape2)

ap_top_terms %>%
  mutate(topic = paste("topic", topic)) %>%
  acast(term ~ topic, value.var = "beta", fill = 0) %>%
  comparison.cloud(colors = c("#F8766D", "#00BFC4"),
                   max.words = 100)

person Julia Silge    schedule 08.08.2017
comment
Спасибо Юлия! Я изучаю ваш код и код джентльмена ниже.... спасибо! - person SChatcha; 08.08.2017
comment
Не могли бы вы дать мне несколько советов, как построить облако слов из бета-версии матрицы. Толщина находится в частоте в моем коде. wordcloud(words = d$term, freq = d$freq, min.freq = 1, max.words=200, random.order=FALSE, rot.per=0,35, colors=brewer.pal(8, Dark2)) - person SChatcha; 20.08.2017

Возьмите подмножество вашего DTM в соответствии со словами каждой темы (dtm[,topterms]) и возьмите суммы столбцов (slam::col_sums) матрицы терминов документа с подмножеством. Например.:

library(topicmodels)
library(tm)
library(wordcloud)
txt <- c(world="Hello hello world world world foo", foo="foo foo bar fizz")
dtm <- DocumentTermMatrix(VCorpus(VectorSource(txt)))
lda <- LDA(dtm, control = list(alpha = 0.1), k = 2)
freqlst <- lapply(
  terms(lda, thres=.2, simplify=F), 
  function(topterms) slam::col_sums(dtm[,topterms])
)
par(mfrow = c(1,2))
invisible(lapply(freqlst, function(x) 
  wordcloud(names(x), x, min.freq = 0)
))
person lukeA    schedule 08.08.2017
comment
Привет LukeA просто быстрый ответ.... Спасибо за ответ. Я попробую и вернусь к вам позже. - person SChatcha; 08.08.2017
comment
@Schatchawan Не беспокойся. - person lukeA; 08.08.2017