1 t5 M& W. @" p ! Z3 P6 q6 e0 o" u5 l# s上面显示了 M2M2 矩阵的情况,它是一个 K∗VK∗V 维的 topic - term矩阵,KK 指主题的数量,VV 指词汇表的大小。M2M2 中每一行都是一个 ϕϕ 分布,也就是主题 ϕkϕk 在 mm 个词上的多项式分布情况,可以通过学习得到。 - x' `0 H& v I/ \ ( R% J. g$ x0 K0 PLDA 文档生成流程; Y! b `6 c- {: t
LDA 假设文档是由多个主题的混合来产生的,每个文档的生成过程如下:8 ]& Y- z- x9 ?, q
{4 D4 {2 ?; c: T8 |从全局的泊松分布参数为 ββ 的分布中生成一个文档的长度 NN" q: ?; w% U; ?8 _. F
从全局的狄利克雷参数为 alphaalpha 的分布中生成一个当前文档的 θθ6 t% L2 M7 A# v5 o' ~* Y: _1 y
对当前文档长度 NN 的每一个字都有6 F( F9 i% G" U/ p' t( N+ L
从 θθ 为参数的多项式分布生成一个主题的下标 znzn & O, Y3 U( L% I2 x( U* b# ^7 b从 θθ 和 zz 共同为参数的多项式分布中,产生一个字 wnwn( r" @% V, U% S b
这些主题基于词的概率分布来产生词,给定文档数据集,LDA 可以学习出,是哪些主题产生了这些文档。 ) Y9 q- h* J0 O( [; z B# X7 b3 ]" s% c7 C `
对于文档生成过程,则有,首先对于文档 nn 中的每一个字,都先从文档矩阵 M1M1 中的 θiθi 中产生一个下标,告诉我们现在要从主题矩阵 M2M2 中的哪一行 ϕmϕm生成当前的字。) G# \3 d, f' W. @0 r0 ?0 D
$ n6 b+ O/ T! o( ]5 ]2 s0 ~) v
5 f; z4 M6 `+ s+ b( N+ E
训练过程(吉布斯采样)/ m- i/ d" }) H0 B6 T7 m5 m7 [
吉布斯采样 (Gibbs Sampling) 首先选取概率向量的一个维度,给定其他维度的变量值当前维度的值,不断收敛来输出待估计的参数。具体地 ' H6 V* H @% M, e1 `2 \' ^ " z, S" u2 O! y! b随机给每一篇文档的每一个词 ww,随机分配主题编号 zz * V# N) ]' P9 d4 M统计每个主题 zizi 下出现字 ww 的数量,以及每个文档 nn 中出现主题 zizi 中的词 ww的数量# w5 r/ I% l- U8 T& v0 N
每次排除当前词 ww 的主题分布 zizi,根据其他所有词的主题分类,来估计当前词 ww 分配到各个主题 z1,z2,…,zkz1,z2,…,zk 的概率,即计算 p(zi|z−i,d,w)p(zi|z−i,d,w) (Gibbs updating rule))。得到当前词属于所有主题z1,z2,…,zkz1,z2,…,zk 的概率分布后,重新为词采样一个新的主题 z1z1。用同样的方法不断更新的下一个词的主题,直到每个文档下的主题分布θnθn 和每个主题下的词分布 ϕkϕk 收敛。 . F: l/ }, E' b2 ]- E( P; w7 N+ S$ F最后输出待估计参数,θnθn 和 ϕkϕk ,每个单词的主题 zn,kzn,k 也可以得到。2 b8 o' ~/ k7 [# C9 U
( Y. p) u4 ~: W2 o9 F/ U
4 }. ~/ P( R0 A- f6 N- R) eLDA 对于每个文档的每一个字都有一个主题下标。但从文档聚类的角度来说,LDA 没有一个文档统一的聚类标签,而是每个字都有一个聚类标签,这个就是主题。LDA 每个字都有可能属于不同的类别,每个文档都有可能属于不同的类别。在大量的迭代后,主题分布和字分布都比较稳定也比较好了,LDA 模型收敛。% M S" p, m/ h
5 O. R8 ~" H. C4 K ! k8 q' Y# u: z( f5 B5 E* N- i5 |6 h( r' t
三、LDA 的参数% W) g% L. G/ }+ S3 r4 ^
αα :表示 document-topic 密度, αα 越高,文档包含的主题更多,反之包含的主题更少* e+ l( x0 }/ n+ q9 {. x- \
# K2 T! p1 G/ h$ u6 e) Y: Q' }
ββ :表示 topic-word 密度, ββ 越高,主题包含的单词更多,反之包含的单词更少 + t2 N7 l! M H' X6 I" Z 6 i" R `! ^8 t+ B2 ]" v主题数量:主题数量从语料中抽取得到,使用 Kullback Leibler Divergence Score 可以获取最好的主题数量。1 G) L# _+ Q' {' f t
+ M3 H# V) R) [0 `( ?3 a主题词数:组成一个主题所需要的词的数量。这些词的数量通常根据需求得到,如果说需求是抽取特征或者关键词,那么主题词数比较少,如果是抽取概念或者论点,那么主题词数比较多。- X6 v: D6 P( g% D! S# p
8 d# N4 y% q5 y
迭代次数:使得 LDA 算法收敛的最大迭代次数 4 }8 z2 H$ s2 P ) v4 d4 _ X3 o4 p q% W; F1 A8 ?) p& K$ S, ^" n4 q' B% h% r- N
四、Running in Python& j! k& Z. D( b3 r) E
准备文档集合# K+ K m' b& U. ~
doc1 = "Sugar is bad to consume. My sister likes to have sugar, but not my father." 8 r' s# D1 V6 `+ F5 Adoc2 = "My father spends a lot of time driving my sister around to dance practice." % f0 I% P* `9 g& \- E. O, @9 A: Q+ Sdoc3 = "Doctors suggest that driving may cause increased stress and blood pressure." # g6 \: |9 j; s9 ~/ Fdoc4 = "Sometimes I feel pressure to perform well at school, but my father never seems to drive my sister to do better.") J0 [) V* h4 J) {( W
doc5 = "Health experts say that Sugar is not good for your lifestyle." $ Z1 M5 v" |% A5 O; O" @8 o9 Z7 D/ I2 S
# 整合文档数据$ Q, R- _, O9 ^
doc_complete = [doc1, doc2, doc3, doc4, doc5] ' t7 c1 Y3 _2 P + \# g- A `* }) h% x$ `" D# n数据清洗和预处理% G' W% L0 J5 ]! B
数据清洗对于任何文本挖掘任务来说都非常重要,在这个任务中,移除标点符号,停用词和标准化语料库(Lemmatizer,对于英文,将词归元)。 ' _7 {& ~ Q" ~ h/ y' e* p# b( H9 l4 o3 r, A" l
from nltk import stopwords5 d2 h' Z$ b! ^4 P$ m0 N2 V
from nltk.stem.wordnet import WordNetLemmatizer7 b& C" a! H. t4 R9 L( @* q
import string % @% M& G* ~. F* ^9 Y * ^: U7 n- r" H! ~+ d' tstop = set(stopwords.words('english')) - w8 A& [% ?& U7 `% ]exclude = set(string.punctuation); g2 X. n: R) e1 _
lemma = WordNetLemmatizer()5 X. B, {) w/ [
- B$ h% z% L- N1 l adef clean(doc): 5 s# `- s' h, b1 E* N- ? stop_free = " ".join([i for i in doc.lower().split() if i not in stop]) # o7 L: L4 q1 Q; ~2 M punc_free = ''.join(ch for ch in stop_free if ch not in exclude)! F% b% [, x% v# ?
normalized = " ".join(lemma.lemmatize(word) for word in punc_free.split()) ) r( [) A5 o9 H+ V; Y; \ return normalized5 u3 u5 g s( U& b& \& Y
* a; J6 g2 p L& jdoc_clean = [clean(doc).split() for doc in doc_complete] + e( F% m3 R/ A7 K" q ) ~9 ]8 @) F Q: M6 u' U1 t准备 Document - Term 矩阵3 y3 {' t$ r7 S( C/ @
语料是由所有的文档组成的,要运行数学模型,将语料转化为矩阵来表达是比较好的方式。LDA 模型在整个 DT 矩阵中寻找重复的词语模式。Python 提供了许多很好的库来进行文本挖掘任务,“genism” 是处理文本数据比较好的库。下面的代码掩饰如何转换语料为 Document - Term 矩阵: " B& F& N! }9 `+ {+ D" y 7 N& m" X+ @. }/ ^5 l- F/ |import genism8 b. r. t& c5 G8 W' w
from gensim import corpora A0 S& d9 h$ k! ^6 v" T8 T( N8 r' D+ {' v9 n ~% t0 i6 T. j1 |
# 创建语料的词语词典,每个单独的词语都会被赋予一个索引# y+ l0 a! X1 h* E
dictionary = corpora.Dictionary(doc_clean)# @% K$ d3 D! v0 }/ c4 D- S! o
! z+ t* W: O8 H" ?! Z0 G
# 使用上面的词典,将转换文档列表(语料)变成 DT 矩阵: U% s" `2 D+ p
doc_term_matrix = [dictionary.doc2bow(doc) for doc in doc_clean]/ E: h* U* b7 {2 [& e6 ^
! `( ]! g. }) ?: q
构建 LDA 模型 8 V& y; r! `: A' R; p创建一个 LDA 对象,使用 DT 矩阵进行训练。训练需要上面的一些超参数,gensim 模块允许 LDA 模型从训练语料中进行估计,并且从新的文档中获得对主题分布的推断。2 `. V% y, j# G+ k" {- _. |+ E