library(tidyverse)theme_set( theme_bw())
通常,当我们在线搜索信息时,有两种主要方法:
另一种方法是通过主题搜索和探索文档。广泛的主题可能与文章中的各个部分(国家事务,体育)有关,但这些部分内或之间可能存在特定主题。
为此,我们需要有关每篇文章主题的详细信息。对该语料库进行手工编码将非常耗时,更不用说在开始编码之前需要知道文档的主题结构。
因此,我们可以使用概率主题模型,分析原始文本文档中的单词的统计算法来揭示语料库和单个文档本身的主题结构。在分析之前,它们不需要对文档进行任何手工编码或标记 - 相反,算法来自对文本的分析。
LDA假定语料库中的每个文档都包含在整个语料库中的混合主题。主题结构是隐藏的 - 我们只能观察文档和文字,而不是主题本身。因为结构是隐藏的(也称为潜在的),所以该方法试图在给定已知单词和文档的情况下推断主题结构。
假设您有以下句子:
Latent Dirichlet分配是一种自动发现这些句子所包含的主题的方法。例如,给定这些句子并询问2个主题,LDA可能会产生类似的东西
您可以推断出主题A是关于食物的主题,主题B是关于可爱动物的主题。但是,LDA没有以这种方式明确地确定主题。它所能做的就是告诉你特定单词与主题相关的概率。
LDA将文档表示为以某些概率单词的主题组合。它假设文档以下列方式生成:在编写每个文档时,您
我们怎么能在前面的例子中生成句子?生成文档D时:
因此,在LDA模型下生成的文件将是“可爱的熊猫吃樱桃和西兰花”(LDA使用的是词袋模型)。
现在假设您有一组文档。你选择了一些固定数量的K.
ķ是要发现的主题,我们希望使用LDA来学习每个文档的主题表示以及与每个主题相关联的单词。怎么做到这一点?一种方式(称为吉布斯采样)如下:
如果先验地知道一组文档的主题结构,LDA可能是有用的。
我们可以使用LDA和主题建模来发现章节与不同主题(即书籍)的关系。
作为预处理,我们将这些分为章节,使用tidytext unnest_tokens将它们分成单词,然后删除stop_words。我们将每一章都视为一个单独的“文档” 。
by_chapter <- books %>%group_by(title) %>%mutate(chapter = cumsum( str_detect(text, regex("^chapter ", ignore_case = TRUE)))) %>%ungroup() %>%count(title_chapter, word, sort = TRUE) %>%ungroup()## Joining, by = "word"word_counts## # A tibble: 104,721 × 3## title_chapter word n## <chr> <chr> <int>## 1 Great Expectations_57 joe 88## 2 Great Expectations_7 joe 70## 3 Great Expectations_17 biddy 63## 4 Great Expectations_27 joe 58## 5 Great Expectations_38 estella 58## 6 Great Expectations_2 joe 56## 7 Great Expectations_23 pocket 53## 8 Great Expectations_15 joe 50## 9 Great Expectations_18 joe 50## 10 The War of the Worlds_16 brother 50## # ... with 104,711 more rows
topicmodels包需要一个DocumentTermMatrix(来自tm包)。我们可以用cast_dtm函数转换为DocumentTermMatrix:
chapters_dtm## <<DocumentTermMatrix (documents: 193, terms: 18215)>>## Non-/sparse entries: 104721/3410774## Sparsity : 97%## Maximal term length: 19## Weighting : term frequency (tf)
现在我们准备创建一个四主题LDA模型。
chapters_lda <- LDA(chapters_dtm, k = 4, control = list(seed = 1234))chapters_lda## A LDA_VEM topic model with 4 topics.
我们从动词开始。
library(tidytext)chapters_lda_td <- tidy(chapters_lda)chapters_lda_td## # A tibble: 72,860 × 3## topic term beta## <int> <chr> <dbl>## 1 1 joe 5.830326e-17## 2 2 joe 3.194447e-57## 3 3 joe 4.162676e-24## 4 4 joe 1.445030e-02## 5 1 biddy 7.846976e-27## 6 2 biddy 4.672244e-69## 7 3 biddy 2.259711e-46## 8 4 biddy 4.767972e-03## 9 1 estella 3.827272e-06## 10 2 estella 5.316964e-65## # ... with 72,850 more rows
我们可以使用dplyr's top_n来查找每个主题中的前5个词:
top_n(5, beta) %>%ungroup() %>%arrange(topic, -beta)top_terms## # A tibble: 20 × 3## topic term beta## <int> <chr> <dbl>## 1 1 elizabeth 0.014107538## 2 1 darcy 0.008814258## 3 1 miss 0.008706741## 4 1 bennet 0.006947431## 5 1 jane 0.006497512
ggplot( aes(term, beta, fill = factor(topic))) +geom_bar(alpha = 0.8, stat
另请注意,LDA()不会为每个主题分配任何标签。它们只是主题1,2,3和4. 我们可以推断这些与每本书有关,但它仅仅是我们的推论。
每一章都是本分析中的“文件”。因此,我们可能想知道哪些主题与每个文档相关联。我们可以把这些章节放回正确的书中吗?
chapters_lda_gamma## # A tibble: 772 × 3## document topic gamma## <chr> <int> <dbl>## 1 Great Expectations_57 1 1.351886e-05## 2 Great Expectations_7 1 1.470726e-05## 3 Great Expectations_17 1 2.117127e-05## 4 Great Expectations_27 1 1.919746e-05## 5 Great Expectations_38 1 3.544403e-01## 6 Great Expectations_2 1 1.723723e-05## 7 Great Expectations_23 1 5.507241e-01## 8 Great Expectations_15 1 1.682503e-02## 9 Great Expectations_18 1 1.272044e-05## 10 The War of the Worlds_16 1 1.084337e-05## # ... with 762 more rows
每行每个主题一个文档。现在我们已经有了这些文档分类,我们可以看到我们的无监督学习在区分四本书方面做得如何。
首先,我们将文档名称重新分为标题和章节:
chapters_lda_gamma <- chapters_lda_gamma %>%separate(document, c("title", "chapter"), sep = "_", convert = TRUE)chapters_lda_gamma## # A tibble: 772 × 4## title chapter topic gamma## * <chr> <int> <int> <dbl>## 1 Great Expectations 57 1 1.351886e-05## 2 Great Expectations 7 1 1.470726e-05## 3 Great Expectations 17 1 2.117127e-05## 4 Great Expectations 27 1 1.919746e-05## 5 Great Expectations 38 1 3.544403e-01## 6 Great Expectations 2 1 1.723723e-05## 7 Great Expectations 23 1 5.507241e-01## 8 Great Expectations 15 1 1.682503e-02## 9 Great Expectations 18 1 1.272044e-05## 10 The War of the Worlds 16 1 1.084337e-05## # ... with 762 more rows
然后我们检查每个章节的正确部分:
ggplot(chapters_lda_gamma, aes(gamma, fill = factor(topic))) +geom_histogram() +facet_wrap(~ title, nrow = 2)## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
我们注意到,几乎所有来自“ 傲慢与偏见”,“世界大战 ”和“ 海底两万里 ”的章节都被确定为一个章节。
chapter_classifications <- chapters_lda_gamma %>%group_by(title, chapter) %>%top_n(1, gamma) %>%ungroup() %>%arrange(gamma)chapter_classifications## # A tibble: 193 × 4## title chapter topic gamma## <chr> <int> <int> <dbl>## 1 Great Expectations 54 3 0.4803234## 2 Great Expectations 22 4 0.5356506## 3 Great Expectations 31 4 0.5464851## 4 Great Expectations 23 1 0.5507241## 5 Great Expectations 33 4 0.5700737## 6 Great Expectations 47 4 0.5802089## 7 Great Expectations 56 4 0.5984806## 8 Great Expectations 38 4 0.6455341## 9 Great Expectations 11 4 0.6689600## 10 Great Expectations 44 4 0.6777974## # ... with 183 more rows
主题建模期望最大化算法中的一个重要步骤是将每个文档中的每个单词分配给一个主题。文档中的单词越多分配给该主题,通常,权重(gamma)将在该文档主题分类上。
通常在使用LDA时,您实际上并不知道文档的基础主题结构。通常,这就是您首先使用LDA分析文本的原因。
数据是1992年发布的文章样本的文档术语矩阵。让我们将它们加载到R中并转换为整齐格式。
## 1 1 adding 1## 2 1 adult 2## 3 1 ago 1## 4 1 alcohol 1## 5 1 allegedly 1## 6 1 allen 1## 7 1 apparently 2## 8 1 appeared 1## 9 1 arrested 1## 10 1 assault 1## # ... with 302,021 more rows
为什么要先整理一下?因为原始的dtm包含停用词 - 我们想在建模数据之前删除它们。然后将数据转换回文档矩阵。
## Sparsity : 99%## Maximal term length: 18## Weighting : term frequency (tf)
每个主题的顶级词是什么样的?
group_by(topic) %>%top_n(5, beta) %>%ungroup() %>%arrange(topic, -beta)top_terms## # A tibble: 20 × 3## topic term beta## <int> <chr> <dbl>## 1 1 soviet 0.009502197## 2 1 government 0.009198486## 3 1 president 0.007046753## 4 1 united 0.006507324## 5 1 people 0.005402784## 6 2 people 0.007454587## 7 2 police 0.006433472## 8 2 city 0.003996852## 9 2 time 0.003369658## 10 2 school 0.003058213## 11 3 court 0.006850723## 12 3 bush 0.006510244## 13 3 president 0.005777216## 14 3 federal 0.005512805## 15 3 house 0.004657550## 16 4 percent 0.023766679## 17 4 million 0.012489935## 18 4 billion 0.009864418## 19 4 market 0.008402463## 20 4 prices 0.006693626top_terms %>%) +coord_flip()
这四个主题通常用于描述:

如果我们设置k=12
我们的结果如何变化?
group_by(topic) %>%top_n(5, beta) %>%ungroup() %>%arrange(topic, -beta)top_terms## # A tibble: 60 × 3## topic term beta## <int> <chr> <dbl>## 1 1 military 0.011691176## 2 1 united 0.011598436## 3 1 iraq 0.010618221## 4 1 president 0.009498227## 5 1 american 0.008253379## 6 2 dukakis 0.009819260## 7 2 bush 0.007300830## 8 2 campaign 0.006366915## 9 2 people 0.006098596## 10 2 school 0.005208529## # ... with 50 more rows
嗯,这些主题似乎更具体,但不易理解。

等。
LDA的某些方面是由直觉思维驱动的。但是我们可以提供辅助方法。
困惑度是概率模型预测样本的程度的统计量度。你估计LDA模型。然后给出由主题表示的理论单词分配,将其与实际主题或文档中单词的分配进行比较。
perplexity为给定模型计算该值的函数。
perplexity(ap_lda)## [1] 2301.814
但是,统计数据本身有点无意义。这种统计数据的好处在于比较不同模型的不同k的困惑度。具有最低困惑度的模型通常被认为是“最佳”。
让我们估算美联社数据集上的一系列LDA模型。
n_topics <- c(2, 4, 10, 20, 50, 100)ap_lda_compare <- n_topics %>%map(LDA, x = ap_dtm, control = list(seed = 1109))geom_point() +y = "Perplexity")
看起来100主题模型具有最低的困惑分数。这会产生什么样的主题?让我们看一下模型产生的前12个主题:
ap_lda_td <- tidy(ap_lda_compare[[6]])top_terms <- ap_lungroup() %>%arrange(topic, -beta)top_terms## # A tibble: 502 × 3## topic term beta## <int> <chr> <dbl>## 1 1 party 0.020029039## 2 1 communist 0.013810107## 3 1 government 0.013221069## 4 1 news 0.013036980## 5 1 soviet 0.011512086ggplot(aes(term, beta, fill = factor(topic))) +geom_bar(alpha = 0.8, stat = "identity", show.legend = FALSE) +facet_wrap(~ topic, scales = "free", ncol = 3) +coord_flip()
我们现在正在获得更具体的主题。问题是我们如何呈现这些结果并以信息方式使用它们。
同样,这也是您作为研究人员时直觉和领域知识非常重要的地方。您可以使用困惑作为决策过程中的一个数据点,但很多时候它只是简单地查看主题本身以及与每个主题相关联的最高概率词来确定结构是否有意义。如果您有一个已知的主题结构,您可以将其与之比较(例如上面的书籍示例),这也很有用。

最受欢迎的见解
3. r语言文本挖掘tf-idf主题建模,情感分析n-gram建模研究
4. python主题建模可视化lda和t-sne交互式可视化
5. r语言文本挖掘nasa数据网络分析,tf-idf和主题建模
7. r语言中对文本数据进行主题模型topic-modeling分析
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69982319/viewspace-2739021/ ,如需转载,请注明出处,否则将追究法律责任。