- m( O& j8 e( W6 o2 g主题数量:主题数量从语料中抽取得到,使用 Kullback Leibler Divergence Score 可以获取最好的主题数量。 ) _$ p+ g* ], F& I2 z 6 [/ v( Z$ `2 s* C/ t) ^主题词数:组成一个主题所需要的词的数量。这些词的数量通常根据需求得到,如果说需求是抽取特征或者关键词,那么主题词数比较少,如果是抽取概念或者论点,那么主题词数比较多。4 \/ I _. C# w. }+ Z
7 l7 ?# {4 [. R; L- u7 f" L迭代次数:使得 LDA 算法收敛的最大迭代次数 ) z+ V9 [" S+ `. X9 U' ]0 t. y* [ f! c, `; s0 S* C! h, u% `8 A7 b/ {# s . `) l+ q" c- Z; R& R) B 4 x. V: D' Z. `% U4 Z6 I四、Running in Python 0 _% S0 F4 Z g: ?% z6 R准备文档集合/ f* Z' t, H+ {+ i q
doc1 = "Sugar is bad to consume. My sister likes to have sugar, but not my father." & ? n- e& D8 adoc2 = "My father spends a lot of time driving my sister around to dance practice."3 Y7 y8 n* \* W9 {- m* N7 O; g3 g
doc3 = "Doctors suggest that driving may cause increased stress and blood pressure." 6 u" q' m' L# wdoc4 = "Sometimes I feel pressure to perform well at school, but my father never seems to drive my sister to do better."* ~1 p, k2 A$ H* r
doc5 = "Health experts say that Sugar is not good for your lifestyle." * y9 c8 I) @! x5 L / d, [9 a1 K% D" n0 Z9 ?+ ^% v# 整合文档数据" H/ i$ \( @- K/ \9 |% k
doc_complete = [doc1, doc2, doc3, doc4, doc5]* K Y1 F$ O5 y2 Z1 b
' p' a' E! [4 O: o# T
数据清洗和预处理 . e4 \; h* {+ \$ l数据清洗对于任何文本挖掘任务来说都非常重要,在这个任务中,移除标点符号,停用词和标准化语料库(Lemmatizer,对于英文,将词归元)。( P$ ~5 o$ Y5 M7 A7 J% F
; w* j! y |- R8 C( D$ @8 q3 Kfrom nltk import stopwords 7 ~9 j7 `3 E" ^) u' ?from nltk.stem.wordnet import WordNetLemmatizer ( K7 i# u; i- G. V; }, C) Simport string , l! A. Z& Z7 }; p* B; t, d 1 F; A+ Z- w+ F, X8 g( ~) I( astop = set(stopwords.words('english')). ~# Z! d9 h" y! u7 ^/ _
exclude = set(string.punctuation) _) \& f! f5 Q( M" q" d! Vlemma = WordNetLemmatizer()* |3 b& V, `( w6 Y3 {: `. c b
0 z5 X9 O* O( M1 R
def clean(doc): V! j W3 B* M- ^, ?% h+ y stop_free = " ".join([i for i in doc.lower().split() if i not in stop])1 u1 |$ `9 K- ]6 K) P8 p
punc_free = ''.join(ch for ch in stop_free if ch not in exclude) 3 X: Y, s1 @! v1 d+ |; t normalized = " ".join(lemma.lemmatize(word) for word in punc_free.split()) % l9 D. M' m4 `9 M2 r: Q' H S return normalized . S/ T! d! M) r ' |( V( z! X) u6 Z$ J$ qdoc_clean = [clean(doc).split() for doc in doc_complete], W# D( x B Z8 q
/ q+ D' X8 G+ `! g( Y4 C3 I. a准备 Document - Term 矩阵5 _3 q* y4 |& P
语料是由所有的文档组成的,要运行数学模型,将语料转化为矩阵来表达是比较好的方式。LDA 模型在整个 DT 矩阵中寻找重复的词语模式。Python 提供了许多很好的库来进行文本挖掘任务,“genism” 是处理文本数据比较好的库。下面的代码掩饰如何转换语料为 Document - Term 矩阵: + W5 u: M1 i& k: U- B4 f" V/ ~1 W5 d' `
import genism ; V) a8 v6 @* p; s+ ]4 I1 yfrom gensim import corpora 4 T# ~3 E* \9 b7 U* R; q5 a* R ; C _% H3 K4 x; h0 I# D# 创建语料的词语词典,每个单独的词语都会被赋予一个索引 - R/ m8 n( D* wdictionary = corpora.Dictionary(doc_clean)1 Q& }- z- k' w- ^4 Z
+ N5 R% d7 ?- s. |- m7 H8 z
# 使用上面的词典,将转换文档列表(语料)变成 DT 矩阵. T5 u! K/ i3 k+ ?' ~( x+ @5 m+ g
doc_term_matrix = [dictionary.doc2bow(doc) for doc in doc_clean]/ M2 F5 f( l) s9 d1 j
8 `/ q& Q2 r0 R. }8 m' @ x. [( [
构建 LDA 模型* r0 C1 V. i( w `
创建一个 LDA 对象,使用 DT 矩阵进行训练。训练需要上面的一些超参数,gensim 模块允许 LDA 模型从训练语料中进行估计,并且从新的文档中获得对主题分布的推断。6 }" |; W+ u4 H4 Q9 V1 P1 t
& D% [4 M) ?1 J) u* u
# 使用 gensim 来创建 LDA 模型对象 / I* i& L# t' G3 n9 h+ B. @Lda = genism.models.ldamodel.LdaModel % F9 A L6 t' v5 g7 p _3 a; I' l. c2 J% J( m; I3 s+ v2 P
# 在 DT 矩阵上运行和训练 LDA 模型 a w. ^ W2 N4 f0 x8 Bldamodel = Lda(doc_term_matrix, num_topics=3, id2word = dictionary, passes=50) : K; ?! i* R, E! B0 W' X$ X8 C/ e, m7 I. Z" }' W4 v# r) n; }0 i
结果 ; C; M/ b; e! o; V. Z- I- ^& x# 输出结果 / ~% u* S/ Y# p! ?7 [& oprint(ldamodel.print_topics(num_topics=3, num_words=3)) * k; @- s1 U) C6 M* h( n! K; V7 n# P8 w& {
[ ! I9 A$ S4 R, X: T '0.168*health + 0.083*sugar + 0.072*bad,$ J f$ o. a2 U/ R/ l
'0.061*consume + 0.050*drive + 0.050*sister, % e8 X) W" O; m) q; @ '0.049*pressur + 0.049*father + 0.049*sister |5 }& x% z0 v$ a
]' B1 c3 D4 `( z5 J# `" l9 {
每一行包含了主题词和主题词的权重,Topic 1 可以看作为“不良健康习惯”,Topic 3 可以看作 “家庭”。 * H1 r0 F: m2 z# M9 d ? |4 H) e, ^( U v6 A
五、提高主题模型结果的一些方法 ( q% {1 \6 J9 P+ J$ ^& F8 \主题模型的结果完全取决于特征在语料库中的表示,但是语料通常表示为比较稀疏的文档矩阵,因此减少矩阵的维度可以提升主题模型的结果。 . U6 d; h% L6 l/ E" B! _/ ?" X% }" Y" ^. o
1. 根据词频调整稀疏矩阵( ~8 h/ i3 |3 F+ Q
根据频率来分布词,高频词更可能出现在结果中,低频词实际上是语料库中的弱特征,对于词频进行分析,可以决定什么频率的值应该被视为阈值。 e0 `" w8 Z. ] & x7 C' n) T! [2. 根据词性标注 (Part of Speech Tag) 调整稀疏矩阵 " C4 e- [! x3 M比起频率特征,词性特征更关注于上下文的信息。主题模型尝试去映射相近的词作为主题,但是每个词在上下文上有可能重要性不同,比如说介词 “IN” 包含 “within”,“upon”, “except”,基数词 “CD” 包含:许多(many),若干(several),个把(a,few)等等,情态助动词 “MD” 包含 “may”,“must” 等等,这些词可能只是语言的支撑词,对实际意义影响不大,因此可以通过词性来消除这些词的影响。9 u% n6 Q) x6 _1 Z; i3 F3 G1 v8 W, G / X1 ^% ~3 o6 X v! l9 U0 u
3. 调整 LDA 的 Batch 大小! k2 U3 V8 [# t/ L' @1 Q
为了得到主题中最重要的主题词,语料可以被分为固定大小的 batch,在这些 batch 上运行 LDA 模型会提供不同的结果,但是最佳的主题词会在这些 batch 上有交集。 . k" K t4 p7 q0 _4 [ + C7 p5 D2 n9 i3 o, O主题模型用于特征选择. M% h! h3 D( u
比如说文本分类任务中,LDA 可以用来选择特征,因为训练数据中含有类别信息,可以在不同类别的结果中,删除相同的、比较常见的主题词,为主题类别提供更好的特征。 : w+ S. W) K$ I7 d: m0 W" K$ c' i7 B; ]
结语 2 N/ }. x- M7 E& `5 a* ~本文主要参考了[1],没有什么公式,用于对 LDA 有一个大概的了解,后面也会更深入 LDA 模型,可以一边运行上面的代码一边感受 LDA 的作用。4 z' G$ K% x- v4 R: U* J
- T1 }1 S8 {! K2 i
参考文献( _- c6 ^ ?% I5 h3 s
[1] https://www.analyticsvidhya.com/blog/2016/08/beginners-guide-to-topic-modeling-in-python9 W% U+ d( @. P2 |* X
5 b, N) W3 D. @7 J8 ?; z T
[2] http://link.springer.com/chapter/10.1007%2F978-3-642-13657-3_433 m; x5 N1 @/ }. g/ u2 O" r! b
———————————————— $ B# a% ]/ Q; ?4 l, g版权声明:本文为CSDN博主「情怀丶」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 $ j+ G9 K N" \原文链接:https://blog.csdn.net/selinda001/article/details/80446766 9 l* n( ~$ A& Y $ f; |; {/ G' Z; F" V# m& ^9 ?! s + V, h6 R. }7 T7 E: I7 C6 e