3 l6 l8 E- w8 ?1 n7 Q( C- }3 N/ X5 v5 b) W( O& _/ t# [. y/ @% e
训练过程(吉布斯采样)& ?8 U) S* M4 V: \3 z
吉布斯采样 (Gibbs Sampling) 首先选取概率向量的一个维度,给定其他维度的变量值当前维度的值,不断收敛来输出待估计的参数。具体地 _+ f3 v" c. a, c+ i! x 0 r: n9 N3 {$ {0 Q$ C随机给每一篇文档的每一个词 ww,随机分配主题编号 zz" N# W* _- S* W& G& w, N- B% s! C
统计每个主题 zizi 下出现字 ww 的数量,以及每个文档 nn 中出现主题 zizi 中的词 ww的数量 , A- d, Q# n7 `3 L1 Q每次排除当前词 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 收敛。% A: w4 F, Z8 o2 w8 `! H2 h( J
最后输出待估计参数,θnθn 和 ϕkϕk ,每个单词的主题 zn,kzn,k 也可以得到。# B0 v, x& J) H/ d. w/ ?; q
! p) k: {& M& k+ s/ e
9 \2 l/ c+ U+ j( v) [" ~7 S
LDA 对于每个文档的每一个字都有一个主题下标。但从文档聚类的角度来说,LDA 没有一个文档统一的聚类标签,而是每个字都有一个聚类标签,这个就是主题。LDA 每个字都有可能属于不同的类别,每个文档都有可能属于不同的类别。在大量的迭代后,主题分布和字分布都比较稳定也比较好了,LDA 模型收敛。 ; ?0 w, D" h9 [. ~. |1 b ` ; M) V/ n' ?1 C l" b0 r; r; d& k' N. M ]
5 Q4 K. i l3 A$ _: X1 P
三、LDA 的参数! G! S5 M& n1 C' i+ f3 L0 w7 i
αα :表示 document-topic 密度, αα 越高,文档包含的主题更多,反之包含的主题更少 " ^7 N- q; s) [' j. a7 L9 C1 ] z. [/ v- t
ββ :表示 topic-word 密度, ββ 越高,主题包含的单词更多,反之包含的单词更少 # ^ |( F( m/ @, X3 ~& G& G% c b
主题数量:主题数量从语料中抽取得到,使用 Kullback Leibler Divergence Score 可以获取最好的主题数量。 / N5 e3 c' K8 Z% ^ 7 e, P2 N o. Q0 X* l& S主题词数:组成一个主题所需要的词的数量。这些词的数量通常根据需求得到,如果说需求是抽取特征或者关键词,那么主题词数比较少,如果是抽取概念或者论点,那么主题词数比较多。 ! X, p$ D1 D8 G5 v9 G. Q2 y3 ~( X, L2 L! I& Q! E
迭代次数:使得 LDA 算法收敛的最大迭代次数 1 d1 |' i# v* j8 m$ K' M8 H2 W, @; p b2 a) b t: B
9 y! R) B8 S |( R! }$ ]+ q+ r 8 O7 r5 T( a8 o6 T四、Running in Python: T8 `1 R/ I" b0 ]; u4 C' B
准备文档集合 - I2 L Y3 O2 U2 z& xdoc1 = "Sugar is bad to consume. My sister likes to have sugar, but not my father." 5 W( w4 L Y) W8 ddoc2 = "My father spends a lot of time driving my sister around to dance practice."% d* t' G8 u/ O
doc3 = "Doctors suggest that driving may cause increased stress and blood pressure." / s7 j9 f* b9 m$ r8 Idoc4 = "Sometimes I feel pressure to perform well at school, but my father never seems to drive my sister to do better." 2 l) T0 L ^. c: Q6 vdoc5 = "Health experts say that Sugar is not good for your lifestyle." ' h. j& s" O, a9 t6 G. x5 X; K- K$ C. F
# 整合文档数据 , ]$ I L) j( ^1 c6 Vdoc_complete = [doc1, doc2, doc3, doc4, doc5]6 j! \6 ~; l7 _$ }1 y d
% K/ r2 q7 U- k. \数据清洗和预处理; r. d- F; z% g: J. }$ U
数据清洗对于任何文本挖掘任务来说都非常重要,在这个任务中,移除标点符号,停用词和标准化语料库(Lemmatizer,对于英文,将词归元)。 ' W" w' X; G( n4 K+ H8 _( R) Z0 | [9 C
from nltk import stopwords 4 y* I% t; S c- N0 C3 hfrom nltk.stem.wordnet import WordNetLemmatizer : y9 m" p9 S0 `+ Uimport string3 q) s7 x! o( y( Q
. V) q1 s( d0 [6 X0 v) @
stop = set(stopwords.words('english')) + r# ]: M+ o/ V4 p' jexclude = set(string.punctuation)2 |8 z6 V8 x8 g1 s; m% H7 a- V
lemma = WordNetLemmatizer()5 }$ P- Q+ U$ ?# c- k. y
1 h) W1 `2 Y5 l' V& [$ o& p
def clean(doc):' o8 ]& }) j: p$ L0 L" D2 w0 h
stop_free = " ".join([i for i in doc.lower().split() if i not in stop]) ' g7 n+ j0 V. T punc_free = ''.join(ch for ch in stop_free if ch not in exclude) 0 J3 e5 f6 P3 l$ }4 O% j2 ? normalized = " ".join(lemma.lemmatize(word) for word in punc_free.split())' C6 A( a/ V) Z$ N
return normalized . D( o5 A; d6 O5 S% q2 B6 y0 q8 j, L T; X - a' Z; K' O& E3 ]; u4 c2 zdoc_clean = [clean(doc).split() for doc in doc_complete]' b- y& O1 Y ~9 h/ V
' A6 R6 \/ Q7 [* s$ [. d* C1 a
准备 Document - Term 矩阵1 _7 b/ O3 L, b& j
语料是由所有的文档组成的,要运行数学模型,将语料转化为矩阵来表达是比较好的方式。LDA 模型在整个 DT 矩阵中寻找重复的词语模式。Python 提供了许多很好的库来进行文本挖掘任务,“genism” 是处理文本数据比较好的库。下面的代码掩饰如何转换语料为 Document - Term 矩阵:/ x1 W, e' C$ }; e6 t
6 t7 p" `' D* U8 W2 D' e+ h. ]
import genism, e! t" T8 I4 m/ |0 B
from gensim import corpora0 B8 W$ |' y) d2 C1 D" t& L C
# f% D& x) e$ `/ O9 g# 创建语料的词语词典,每个单独的词语都会被赋予一个索引5 s, m! B* q6 M2 ^8 m
dictionary = corpora.Dictionary(doc_clean)6 z w6 T1 _. m* U
B7 ^' e% ^# r/ ~# 使用上面的词典,将转换文档列表(语料)变成 DT 矩阵3 y1 g/ t) b; H. x P
doc_term_matrix = [dictionary.doc2bow(doc) for doc in doc_clean]$ ^: y0 j! t/ V& f' i! t