R语言中对文本数据进行主题模型topicmodeling分析

主题建模

在文本挖掘中,咱们常常收集一些文档集合,例如博客文章或新闻文章,咱们但愿将其分红天然组,以便咱们能够分别理解它们。主题建模是对这些文档进行无监督分类的一种方法,相似于对数字数据进行聚类,即便咱们不肯定要查找什么,也能够找到天然的项目组。算法

潜在狄利克雷分配(LDA)是拟合主题模型特别流行的方法。它将每一个文档视为主题的混合体,并将每一个主题看做是单词的混合体。这容许文档在内容方面相互“重叠”,而不是分离成离散的组,以反映天然语言的典型用法。ide

R语言中对文本数据进行主题模型topicmodeling分析

结合主题建模的文本分析流程图。topicmodels包采用Document-Term Matrix做为输入,并生成一个能够经过tidytext进行处理的模型,以即可以使用dplyr和ggplot2对其进行处理和可视化。
clipboard.png函数

如图所示,咱们可使用 文本原理来处理主题建模 。工具

潜在狄利克雷分配

潜在Dirichlet分配是主题建模中最经常使用的算法之一。 学习

每一个文档都是主题的混合体。咱们设想每一个文档可能包含来自几个主题的文字,特别是比例。例如,在双主题模型中,咱们能够说“文档1是90%的主题A和10%的主题B,而文档2是30%的主题A和70%的主题B.”测试

每一个主题都是词汇的混合。例如,咱们能够想象一个美国新闻的两个主题模型,一个话题是“政治”,一个是“娱乐”。政治话题中最多见的词语多是“总统”,“国会”和“政府“,而娱乐主题能够由诸如”电影“,”电视“和”演员“之类的词组成。 spa

LDA是一种同时估计这两种状况的数学方法:查找与每一个主题相关的单词混合,同时肯定描述每一个文档的主题混合。这个算法有不少现有的实现,咱们将深刻探讨其中的一个。code

library(topicmodels)data("AssociatedPress")AssociatedPress

  : term frequency (tf)

咱们可使用LDA()topicmodels包中的函数设置k = 2来建立两个主题的LDA模型。对象

实际上几乎全部的主题模型都会使用更大的模型k,但咱们很快就会看到,这种分析方法能够扩展到更多的主题。token

此函数返回一个包含模型拟合完整细节的对象,例如单词如何与主题关联以及主题如何与文档关联。

# set a seed so that the output of the model is predictableap_lda <- LDA(AssociatedPress,k =2,control =list(seed =1234))ap_lda

拟合模型是“简单部分”:分析的其他部分将涉及使用整理tidytext软件包中的函数来探索和解释模型。

单词主题几率

tidytext包提供了这种方法来提取每一个主题的每一个词的几率,称为ββ (“测试版”)。

## # A tibble: 20,946 x 3##    topic term          beta##            ##  1    1 aaron      1.69e-12##  2    2 aaron      3.90e- 5##  3    1 abandon    2.65e- 5##  4    2 abandon    3.99e- 5##  5    1 abandoned  1.39e- 4##  6    2 abandoned  5.88e- 5##  7    1 abandoning 2.45e-33##  8    2 abandoning 2.34e- 5##  9    1 abbott    2.13e- 6## 10    2 abbott    2.97e- 5## # ... with 20,936 more rows

clipboard.png

R语言中对文本数据进行主题模型topicmodeling分析
每一个主题中最多见的术语

这种可视化让咱们了解从文章中提取的两个主题。话题1中最多见的词语包括“百分比”,“百万”,“十亿”和“公司”,这代表它可能表明商业或财务新闻。话题2中最多见的包括“总统”,“政府”和“苏维埃”,表示这个话题表明政治新闻。

做为替代方案,咱们能够认为有条款最大的区别在ββ在主题1和主题2之间。

## # A tibble: 198 x 4##    term              topic1      topic2 log_ratio##                            ##  1 administration 0.000431  0.00138        1.68##  2 ago            0.00107  0.000842      -0.339##  3 agreement      0.000671  0.00104        0.630##  4 aid            0.0000476 0.00105        4.46##  5 air            0.00214  0.000297      -2.85##  6 american      0.00203  0.00168        -0.270##  7 analysts      0.00109  0.000000578  -10.9##  8 area          0.00137  0.000231      -2.57##  9 army          0.000262  0.00105        2.00## 10 asked          0.000189  0.00156        3.05## # ... with 188 more rows

图显示了这两个主题之间差别最大的词。

clipboard.png

R语言中对文本数据进行主题模型topicmodeling分析
图β中差别最大的词β 在主题2和主题1之间

咱们能够看到,话题2中更常见的词包括“民主”和“共和党”等政党,以及“dukakis”和“gorbachev”等政治家的名字。主题1的特色是“日元”和“美圆”等货币以及“指数”,“价格”和“利率”等金融术语。这有助于确认算法肯定的两个主题是政治和财务新闻。

文档 - 主题几率

除了将每一个主题评估为单词混合以外,LDA还将每一个文档建模为混合主题。咱们能够检查每一个文档的每一个主题几率,称为γγ(“伽玛”),其matrix = "gamma"论点是tidy()。

## # A tibble: 4,492 x 3##    document topic    gamma##          ##  1        1    1 0.248##  2        2    1 0.362##  3        3    1 0.527##  4        4    1 0.357##  5        5    1 0.181##  6        6    1 0.000588##  7        7    1 0.773##  8        8    1 0.00445##  9        9    1 0.967## 10      10    1 0.147## # ... with 4,482 more rows

这些值中的每个都是该文档中从该主题生成的单词的估计比例。例如,该模型估计文档1中单词的大约24.8%是从主题1生成的。

咱们能够看到,这些文档中的许多文档都是从两个主题的混合中抽取出来的,但文档6几乎彻底是从主题2中得出的,其中有一个γγ从主题1接近零。为了检查这个答案,咱们能够tidy()使用文档术语矩阵,并检查该文档中最多见的词。

## # A tibble: 287 x 3##    document term          count##                ##  1        6 noriega          16.##  2        6 panama          12.##  3        6 jackson          6.##  4        6 powell            6.##  5        6 administration    5.##  6        6 economic          5.##  7        6 general          5.##  8        6 i                5.##  9        6 panamanian        5.## 10        6 american          4.## # ... with 277 more rows

根据最多见的词汇,这彷佛是一篇关于美国政府与巴拿马独裁者曼努埃尔诺列加之间关系的文章,这意味着该算法将其置于专题2(做为政治/国家新闻)是正确的。

例子

在考察一个统计方法时,在一个很是简单的状况下,你能够知道“正确的答案”。例如,咱们能够收集一组明确与四个不一样主题相关的文档,而后执行主题建模,以查看该算法是否能够正确区分这四个组。这让咱们仔细检查该方法是否有用,并了解它如何以及什么时候会出错。咱们将使用经典文献中的一些数据来尝试。

假设一个破坏者闯入你的书房并撕毁你的四本书:

Charles Dickens的伟大指望

HG Wells 的世界大战

Jules Verne 在海底的两万里

傲慢与偏见简·奥斯汀

咱们将使用第3章介绍的gutenbergr包检索这四本书的内容。

titles <- c("Twenty Thousand Leagues under the Sea","The War of the Worlds","Pride and Prejudice","Great Expectations")

做为预处理,咱们将它们分红不一样的章节,使用tidytext unnest_tokens()将它们分离成单词,而后删除stop_words。咱们将每一章都视为一个单独的“文档”,每一个章节都有一个像“ Great Expectations_1或”这样的名字Pride and Prejudice_11。(在其余应用程序中,每一个文档多是一篇报纸文章或一篇博客文章)。

## # A tibble: 104,721 x 3##    document                word        n##                          ##  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

章节中的LDA

如今咱们的数据框word_counts是整齐的,每行一个文档,但topicmodels包须要一个DocumentTermMatrix。 咱们能够将每行一个令牌转换为DocumentTermMatrix带有tidytext的表cast_dtm()。

chapters_dtm <- word_counts %>%  cast_dtm(document, word, n)chapters_dtm

而后,咱们可使用该LDA()功能建立一个四主题模型。在这种状况下,咱们知道咱们正在寻找四个主题,由于有四本书; 在其余问题中,咱们可能须要尝试一些不一样的值k。

chapters_lda <- LDA(chapters_dtm,k =4,control =list(seed =1234))chapters_lda

## A LDA_VEM topic model with 4 topics.

就像咱们在美联社的数据中所作的那样,咱们能够检查每一个主题的每一个词的几率。

## # A tibble: 72,860 x 3##    topic term        beta##          ##  1    1 joe    5.83e-17##  2    2 joe    3.19e-57##  3    3 joe    4.16e-24##  4    4 joe    1.45e- 2##  5    1 biddy  7.85e-27##  6    2 biddy  4.67e-69##  7    3 biddy  2.26e-46##  8    4 biddy   4.77e- 3##  9    1 estella 3.83e- 6## 10    2 estella 5.32e-65## # ... with 72,850 more rows

这已将模型转换为每行一个主题的单行格式。对于每一个组合,该模型计算该术语从该主题生成的几率。例如,术语“joe”从主题1,2或3产生几乎为零的几率,但它占主题4的1.45%。

咱们可使用dplyr top_n()来查找每一个主题中的前5个术语。

top_terms <- chapter_topics %>%  group_by(topic) %>%  top_n(5, beta) %>%  ungroup() %>%  arrange(topic, -beta)top_terms

## # A tibble: 20 x 3##    topic term        beta##          ##  1    1 elizabeth 0.0141##  2    1 darcy    0.00881##  3    1 miss      0.00871##  4    1 bennet    0.00695##  5    1 jane      0.00650##  6    2 captain  0.0155##  7    2 nautilus  0.0131##  8    2 sea      0.00885##  9    2 nemo      0.00871## 10    2 ned      0.00803## 11    3 people    0.00680## 12    3 martians  0.00651## 13    3 time      0.00535## 14    3 black    0.00528## 15    3 night    0.00448## 16    4 joe      0.0145## 17    4 time      0.00685## 18    4 pip      0.00682## 19    4 looked    0.00637## 20    4 miss      0.00623

ggplot2可视化

clipboard.png

R语言中对文本数据进行主题模型topicmodeling分析

按文档分类

本分析中的每一个文档都表明一个章节。所以,咱们可能想知道哪些主题与每一个文档相关联。

## # A tibble: 772 x 3##    document                topic    gamma##                            ##  1 Great Expectations_57        1 0.0000135##  2 Great Expectations_7        1 0.0000147##  3 Great Expectations_17        1 0.0000212##  4 Great Expectations_27        1 0.0000192##  5 Great Expectations_38        1 0.354##  6 Great Expectations_2        1 0.0000172##  7 Great Expectations_23        1 0.551##  8 Great Expectations_15        1 0.0168##  9 Great Expectations_18        1 0.0000127## 10 The War of the Worlds_16    1 0.0000108## # ... with 762 more rows

这些值中的每个都是该文档中从该主题生成的单词的估计比例。例如,该模型估计,Great Expectations_57文档中的每一个单词只有来自主题1(“傲慢与偏见”)的几率为0.00135%。

如今咱们有了这些话题几率,咱们能够看到咱们的无监督学习在区分四本书方面作得如何。咱们但愿书中的章节大部分(或彻底)都是从相应的主题中产生的。

首先,咱们将文档名称从新分为标题和章节,以后咱们能够将每一个文档的每一个主题几率可视化。

## # A tibble: 772 x 4##    title                chapter topic    gamma##                          ##  1 Great Expectations        57    1 0.0000135##  2 Great Expectations          7    1 0.0000147##  3 Great Expectations        17    1 0.0000212##  4 Great Expectations        27    1 0.0000192##  5 Great Expectations        38    1 0.354##  6 Great Expectations          2    1 0.0000172##  7 Great Expectations        23    1 0.551##  8 Great Expectations        15    1 0.0168##  9 Great Expectations        18    1 0.0000127## 10 The War of the Worlds      16    1 0.0000108## # ... with 762 more rows

clipboard.png

R语言中对文本数据进行主题模型topicmodeling分析

咱们注意到,几乎全部来自“ 傲慢与偏见”,“世界大战 ”和“ 海底二万里 ”的章节都被认为是一个单独的主题。

chapter_classifications <- chapters_gamma %>%  group_by(title, chapter) %>%  top_n(1, gamma) %>%  ungroup()chapter_classifications

而后,咱们能够将每本书与每本书的“共识”主题(其章节中最多见的主题)进行比较,并查看哪些主题常常被错误识别。

经过词汇分配:augment

LDA算法的一个步骤是将每一个文档中的每一个单词分配给一个主题。文档中的单词越多,则一般gamma该文档 - 主题分类的权重越大()。

咱们可能想要采用原始文档字对,并查找每一个文档中的哪些字词分配给哪一个主题。

assignments <- augment(chapters_lda,data =chapters_dtm)assignments

.topic每一个文档中每一个术语都分配了一个主题。(augment老是以开头添加额外的列.,以防止覆盖现有的列)。咱们能够将此assignments表格与共识书籍标题结合起来,找出哪些词语被错误分类。

## # A tibble: 104,721 x 6##    title              chapter term  count .topic consensus##                      ##  1 Great Expectations      57 joe    88.    4. Great Expectations##  2 Great Expectations      7 joe    70.    4. Great Expectations##  3 Great Expectations      17 joe      5.    4. Great Expectations##  4 Great Expectations      27 joe    58.    4. Great Expectations##  5 Great Expectations      2 joe    56.    4. Great Expectations##  6 Great Expectations      23 joe      1.    4. Great Expectations##  7 Great Expectations      15 joe    50.    4. Great Expectations##  8 Great Expectations      18 joe    50.    4. Great Expectations##  9 Great Expectations      9 joe    44.    4. Great Expectations## 10 Great Expectations      13 joe    40.    4. Great Expectations## # ... with 104,711 more rows

真正的book(title)和分配给它的book()的组合consensus对于进一步的探索是有用的。例如,咱们能够将混淆矩阵可视化,使用dplyr's count()和ggplot2 geom_tile显示一本书中的单词被分配给另外一本书的频率。

clipboard.png

R语言中对文本数据进行主题模型topicmodeling分析
混淆矩阵显示了LDA分配每本书的单词的位置。这张表的每一行都表明每一个单词来自的真实书籍,每一列表明它分配的书籍。

什么是最多见的错误的话?

wrong_words <- assignments %>%  filter(title != consensus)wrong_words

## # A tibble: 3,500 x 4##    title              consensus            term        n##                                      ##  1 Great Expectations Pride and Prejudice  love      44.##  2 Great Expectations Pride and Prejudice  sergeant  37.##  3 Great Expectations Pride and Prejudice  lady      32.##  4 Great Expectations Pride and Prejudice  miss      26.##  5 Great Expectations The War of the Worlds boat      25.##  6 Great Expectations Pride and Prejudice  father    19.##  7 Great Expectations The War of the Worlds water      19.##  8 Great Expectations Pride and Prejudice  baby      18.##  9 Great Expectations Pride and Prejudice  flopson    18.## 10 Great Expectations Pride and Prejudice  family    16.## # ... with 3,490 more rows

咱们能够看到, 也经常将一些词语分配给“世界的傲慢与偏见”或“战争”。对于其中的一些词,如“爱”和“女士”,这是由于它们在“傲慢与偏见”中更常见(咱们能够经过检查计数来证明)。

另外一方面,有一些错误分类的词在他们错误分配的小说中从未出现过。例如,咱们能够确认只出如今“flopson” 远大前程,即便它分配给了“傲慢与偏见” 。

word_counts %>%  filter(word == "flopson")

## # A tibble: 3 x 3##  document              word        n##                    ## 1 Great Expectations_22 flopson    10## 2 Great Expectations_23 flopson    7## 3 Great Expectations_33 flopson    1

替代性LDA实现

LDA()topicmodels包中的函数只是潜在Dirichlet分配算法的一个实现。例如,mallet包(Mimno 2013)实现了一个用于文本分类工具的MALLET Java包的包装,而tidytext包也为该模型输出提供了整理器。

library(mallet)# create a vector with one string per chaptercollapsed

然而,一旦模型建立完成,咱们就能够以几乎相同的方式使用本章其他部分描述的函数tidy()和augment()函数。这包括提取每一个主题中的单词几率或每一个文档中的主题。

可使用ggplot2以与LDA输出相同的方式探索和可视化模型。

相关文章
相关标签/搜索