关于数据挖掘:R语言之文本分析主题建模LDA

5次阅读

共计 9226 个字符,预计需要花费 24 分钟才能阅读完成。

原文链接:http://tecdat.cn/?p=3897

原文出处:拓端数据部落公众号

相干视频:文本开掘:主题模型(LDA)及 R 语言实现剖析游记数据

文本开掘:主题模型(LDA)及 R 语言实现剖析游记数据

时长 12:59


文本剖析:主题建模

library(tidyverse)
theme\_set(theme\_bw())

指标

  • 定义主题建模
  • 解释 Latent Dirichlet 以及此过程的工作原理
  • 演示如何应用 LDA 从一组已知主题中找到主题构造
  • 演示如何应用 LDA 从一组未知主题中找到主题构造
  • 确定 k
  • 抉择适当参数的办法

主题建模

通常,当咱们在线搜寻信息时,有两种次要办法:

  1. 关键字 – 应用搜索引擎并输出与咱们想要查找的内容相干的单词
  2. 链接。链接的页面可能共享类似或相干的内容。

另一种办法是通过主题搜寻和摸索文档。宽泛的主题可能与文章中的各个局部(国家事务,体育)无关,但这些局部内或之间可能存在特定主题。

为此,咱们须要无关每篇文章主题的详细信息。对该语料库进行手工编码将十分耗时,更不用说在开始编码之前须要晓得文档的主题构造。

因而,咱们能够应用概率主题模型,剖析原始文本文档中的单词的统计算法来揭示语料库和单个文档自身的主题构造。在剖析之前,它们不须要对文档进行任何手工编码或标记 – 相同,算法来自对文本的剖析。

潜在 Dirichlet 调配

LDA 假设语料库中的每个文档都蕴含在整个语料库中的混合主题。主题构造是暗藏的 – 咱们只能察看文档和文字,而不是主题自身。因为构造是暗藏的(也称为潜在的),所以该办法试图在给定已知单词和文档的状况下推断主题构造。

食物和动物

假如您有以下句子:

  1. 我早餐吃了香蕉和菠菜。
  2. 我喜爱吃西兰花和香蕉。
  3. 龙猫和小猫很可恶。
  4. 我姐姐昨天收养了一只小猫。
  5. 看看这只可恶的仓鼠嚼着一块西兰花。

Latent Dirichlet 调配是一种主动发现这些句子所蕴含的主题的办法。例如,给定这些句子并询问 2 个主题,LDA 可能会产生相似的货色

  • 句子 1 和 2:100%主题 A.
  • 句子 3 和 4:100%主题 B.
  • 句子 5:60%主题 A,40%主题 B.
  • 主题 A:30%西兰花,15%香蕉,10%早餐,10%咀嚼,……
  • 主题 B:20%龙猫,20%小猫,20%可恶,15%仓鼠,……

您能够推断出主题 A 是对于食物的主题,主题 B 是对于可恶动物的主题。然而,LDA 没有以这种形式明确地确定主题。它所能做的就是通知你特定单词与主题相干的概率。

LDA 文档构造

LDA 将文档示意为以某些概率单词的主题组合。它假如文档以下列形式生成:在编写每个文档时,您

  • 确定单词数 N.
  • 为文档抉择主题(依据 K 个主题)
  • 例如,假如咱们下面有两个食物和可恶的动物主题。
  • 通过以下形式生成文档中的每个单词:
  • 首先抉择一个主题(依据您在下面采样的调配; 例如,您能够抉择 1 / 3 概率的食物主题和 2 / 3 概率的可恶动物主题)。
  • 而后应用主题生成单词自身(依据主题调配)。例如,食物主题可能输入概率为 30%的“西兰花”,概率为 15%的“香蕉”,依此类推。

咱们怎么能在后面的例子中生成句子?生成文档 D 时:

  • D 将是一半对于食物和一半对于可恶动物。
  • 抉择 5 为 D 的单词数
  • 从食物主题中抉择第一个词,而后给出“西兰花”这个词。
  • 抉择第二个词来自可恶的动物主题,如“熊猫”。
  • 抉择第三个词来自可恶的动物主题,如“可恶”。
  • 抉择第四个词来源于食物主题,如“樱桃”。
  • 从食物主题中选出第五个词,如“吃”。

因而,在 LDA 模型下生成的文件将是“可恶的熊猫吃樱桃和西兰花”(LDA 应用的是词袋模型)。

通过 LDA 学习主题模型

当初假如您有一组文档。你抉择了一些固定数量的 K.

ķ是要发现的主题,咱们心愿应用 LDA 来学习每个文档的主题示意以及与每个主题相关联的单词。怎么做到这一点?一种形式(称为吉布斯采样)如下:

  • 浏览每个文档,并将文档中的每个单词随机调配给 K 中的一个ķ 主题
  • 但因为它是随机的,这不是一个十分精确的构造。
  • 换句话说,在这一步中,咱们假如除了以后单词之外的所有主题调配都是正确的,而后应用咱们的文档生成模型更新以后单词的赋值。
  • 反复上一步骤很屡次,你最终会达到一个大抵稳固的状态
  • 您能够应用这些调配来预计两件事:
  1. 每个文档的主题(通过计算调配给该文档中每个主题的单词的比例)
  2. 与每个主题相干的单词(通过计算调配给每个主题的单词的比例)

具备已知主题构造的 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

潜在狄利克雷调配 (latnet Dirichlet allocation, LDA) 模型

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.
  • 在这种状况下,咱们晓得有四个主题,因为有四本书; 这是理解潜在主题构造的价值
  • seed = 1234 设置随机迭代过程的终点。如果咱们没有设置种子,那么每次运行脚本时咱们都能够估算出略有不同的模型

咱们从动词开始。

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

 

  • 这些主题与四本书非常明显相干
  • “nemo”,“sea”和“nautilus”属于海底两万里
  • “jane”,“darcy”和“elizabeth”属于高傲与偏见

另请留神,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 时,您实际上并不知道文档的根底主题构造。通常,这就是您首先应用 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.006693626

top_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\_l
ungroup() %>%
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.011512086


ggplot(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()

咱们当初正在取得更具体的主题。问题是咱们如何出现这些后果并以信息形式应用它们。

同样,这也是您作为钻研人员时直觉和畛域常识十分重要的中央。您能够应用困惑作为决策过程中的一个数据点,但很多时候它只是简略地查看主题自身以及与每个主题相关联的最高概率词来确定构造是否有意义。如果您有一个已知的主题构造,您能够将其与之比拟(例如下面的书籍示例),这也很有用。


最受欢迎的见解

1. 探析大数据期刊文章钻研热点

2.618 网购数据盘点 - 剁手族在关注什么

3.r 语言文本开掘 tf-idf 主题建模,情感剖析 n -gram 建模钻研

4.python 主题建模可视化 lda 和 t -sne 交互式可视化

5.r 语言文本开掘 nasa 数据网络剖析,tf-idf 和主题建模

6.python 主题 lda 建模和 t -sne 可视化

7.r 语言中对文本数据进行主题模型 topic-modeling 剖析

8.r 语言对 nasa 元数据进行文本开掘的主题建模剖析

9.python 爬虫进行 web 抓取 lda 主题语义数据分析

正文完
 0