/ ]$ ]. Q! o1 L+ u3 g f: U a% M% S6 _* L4 O
LDA 对于每个文档的每一个字都有一个主题下标。但从文档聚类的角度来说,LDA 没有一个文档统一的聚类标签,而是每个字都有一个聚类标签,这个就是主题。LDA 每个字都有可能属于不同的类别,每个文档都有可能属于不同的类别。在大量的迭代后,主题分布和字分布都比较稳定也比较好了,LDA 模型收敛。 8 X$ ?7 E, N2 }& B# n* `0 o 3 Z& u$ M) ]: v6 y X3 v: j! E; B) L7 o/ ?. ~3 V: u& P! S
0 ^: L, ?4 ]* J, E. o
三、LDA 的参数( L9 Q1 k, \! b/ Q2 `
αα :表示 document-topic 密度, αα 越高,文档包含的主题更多,反之包含的主题更少 2 d8 _0 {2 Z6 i0 F' A& r% a0 U+ o. y4 [: ]4 m% @
ββ :表示 topic-word 密度, ββ 越高,主题包含的单词更多,反之包含的单词更少* x1 O! M* P- d9 x4 n" H% `
3 V3 G) u' w: p" G- c" a1 @主题数量:主题数量从语料中抽取得到,使用 Kullback Leibler Divergence Score 可以获取最好的主题数量。 # }5 c. i" {1 f: K/ |7 ~; v: t0 B) L8 K
主题词数:组成一个主题所需要的词的数量。这些词的数量通常根据需求得到,如果说需求是抽取特征或者关键词,那么主题词数比较少,如果是抽取概念或者论点,那么主题词数比较多。" V+ ?8 {0 R5 H2 i0 ~4 j+ ~; z2 F6 N
% C& [( Q- f' W- D' O* h" S6 Q. Q
迭代次数:使得 LDA 算法收敛的最大迭代次数. q$ N7 I" {* M
+ H$ h3 ]. T+ m% Y
& f0 ~" O$ g. G: p! u' w/ a& X# g9 B6 c' k2 F
四、Running in Python- t d% o: S2 ~5 t+ ~8 @
准备文档集合! T& a' R( y8 p4 V- \. n
doc1 = "Sugar is bad to consume. My sister likes to have sugar, but not my father." / W: J2 W% d( e5 \! Adoc2 = "My father spends a lot of time driving my sister around to dance practice." 6 S! ]6 Q0 Q* T2 K4 v& odoc3 = "Doctors suggest that driving may cause increased stress and blood pressure."3 B3 X& M7 h' F* @& p
doc4 = "Sometimes I feel pressure to perform well at school, but my father never seems to drive my sister to do better." ' U' b8 L* \4 ^doc5 = "Health experts say that Sugar is not good for your lifestyle."! X2 i \& Q I, t- U
7 G$ g' e5 A" ?' K" u: _
# 整合文档数据+ i( v( L+ C0 S& n& L
doc_complete = [doc1, doc2, doc3, doc4, doc5] / c3 o0 d n/ T0 D- ?8 F% ?/ e3 r% R; \9 T0 y& B: W+ C8 V) ?
数据清洗和预处理( g) G0 V$ b# N/ [+ f: q
数据清洗对于任何文本挖掘任务来说都非常重要,在这个任务中,移除标点符号,停用词和标准化语料库(Lemmatizer,对于英文,将词归元)。 . L( ]* O- ?/ Q: d" U# R' s2 D$ v7 y# q6 S" Z4 h4 _8 H! o' t
from nltk import stopwords& M, [0 H% p+ \0 T! E
from nltk.stem.wordnet import WordNetLemmatizer ?4 P4 \' `/ M2 q2 O3 Z4 qimport string3 D/ p; j7 |) Y t+ z
8 l& J# D/ P% a* G# W4 _stop = set(stopwords.words('english')) 6 q8 f: m; Z1 K4 F% yexclude = set(string.punctuation)- L- N, l! W' f/ D
lemma = WordNetLemmatizer()$ T/ Q; F" ]) h' C& g. u: D
/ t5 l/ j: m/ F* m; Z: a- X
def clean(doc): + l% L9 ~) _6 T1 I. q4 K& R$ f stop_free = " ".join([i for i in doc.lower().split() if i not in stop]) , V/ L0 R, @# Z% F6 H ]0 |/ G: p punc_free = ''.join(ch for ch in stop_free if ch not in exclude) $ X1 s9 y6 M0 g3 P5 @, v# \7 J: V normalized = " ".join(lemma.lemmatize(word) for word in punc_free.split()) + ~* I! u& a3 D/ b' u r& t return normalized & b h5 G) N4 ?' ]5 U; }& C3 h6 w ) W# F0 ~4 p7 Q9 z& p/ `doc_clean = [clean(doc).split() for doc in doc_complete]: z& M) j2 l- o4 q7 T4 d$ D" u
: Q1 |8 e) j: B7 T2 X$ D2 v
准备 Document - Term 矩阵 / j: c" R3 b; R* w* [) a语料是由所有的文档组成的,要运行数学模型,将语料转化为矩阵来表达是比较好的方式。LDA 模型在整个 DT 矩阵中寻找重复的词语模式。Python 提供了许多很好的库来进行文本挖掘任务,“genism” 是处理文本数据比较好的库。下面的代码掩饰如何转换语料为 Document - Term 矩阵:4 m" E. m8 B+ j3 P/ \
$ Y1 \0 K. _+ C' T
import genism 4 r' I0 {( Z+ `5 ~from gensim import corpora 0 Q1 r Y% }3 y3 N6 x# X1 d6 M. c( m- p
# 创建语料的词语词典,每个单独的词语都会被赋予一个索引 $ _ G# u. `& f, F) q! `dictionary = corpora.Dictionary(doc_clean) * `9 }$ J# B& {+ C6 f ; t& T# g; w, d: p& n5 z* H! K7 x# 使用上面的词典,将转换文档列表(语料)变成 DT 矩阵 % ]: ~+ E5 b( l& t; ]4 _doc_term_matrix = [dictionary.doc2bow(doc) for doc in doc_clean] 0 h7 i9 D) H( T- i* P2 n0 I% q5 B7 M! v2 Z! H& {
构建 LDA 模型/ }( [5 r7 ^9 E, c0 S/ H
创建一个 LDA 对象,使用 DT 矩阵进行训练。训练需要上面的一些超参数,gensim 模块允许 LDA 模型从训练语料中进行估计,并且从新的文档中获得对主题分布的推断。 : L& G& b4 U3 _; x, a( [0 L % {# x* |) q- ~; Y# 使用 gensim 来创建 LDA 模型对象! v" j7 o8 I$ m$ K7 I! ?/ y! J
Lda = genism.models.ldamodel.LdaModel , E7 s0 x0 y7 U' g, s) c+ t" K/ z5 B2 ^8 @- s
# 在 DT 矩阵上运行和训练 LDA 模型 - j( \9 l5 m- ?ldamodel = Lda(doc_term_matrix, num_topics=3, id2word = dictionary, passes=50) ! P. B5 T1 _' {2 j7 e8 ^0 h7 G4 K* | R/ B. w
结果 + J. O+ m% {2 I8 |# 输出结果- u5 G, U) m4 i( p8 m9 R
print(ldamodel.print_topics(num_topics=3, num_words=3)) # I1 m' T& s! P4 C , s. h+ X, w, W" I, F0 k Y5 b[ 9 {( p$ d5 _ C8 [: \ '0.168*health + 0.083*sugar + 0.072*bad, / L$ \1 I! w0 }+ B3 _8 s '0.061*consume + 0.050*drive + 0.050*sister, 4 Y/ z9 Y0 q' S) I1 ^( T! c/ i0 \ '0.049*pressur + 0.049*father + 0.049*sister6 U- j5 p& ~7 E( I# D4 y
] 9 m; g2 F2 F9 G+ P每一行包含了主题词和主题词的权重,Topic 1 可以看作为“不良健康习惯”,Topic 3 可以看作 “家庭”。' \5 @3 F. g7 w1 C0 ~/ N; u
1 v, \! |, x1 Y( x
五、提高主题模型结果的一些方法 ' ]* f; D' v% c; U) m* o: `主题模型的结果完全取决于特征在语料库中的表示,但是语料通常表示为比较稀疏的文档矩阵,因此减少矩阵的维度可以提升主题模型的结果。 ! Z; C0 x; Q4 a' o* `0 c+ y) P/ q1 w# |+ V
1. 根据词频调整稀疏矩阵0 v3 t# B" b3 U1 I8 B
根据频率来分布词,高频词更可能出现在结果中,低频词实际上是语料库中的弱特征,对于词频进行分析,可以决定什么频率的值应该被视为阈值。 y9 h4 H7 N8 M s/ U7 X# n$ `. V4 U+ i
2. 根据词性标注 (Part of Speech Tag) 调整稀疏矩阵 ) N! R" C( i* }& h比起频率特征,词性特征更关注于上下文的信息。主题模型尝试去映射相近的词作为主题,但是每个词在上下文上有可能重要性不同,比如说介词 “IN” 包含 “within”,“upon”, “except”,基数词 “CD” 包含:许多(many),若干(several),个把(a,few)等等,情态助动词 “MD” 包含 “may”,“must” 等等,这些词可能只是语言的支撑词,对实际意义影响不大,因此可以通过词性来消除这些词的影响。- x+ B% h2 g8 [ 6 J0 q# A. C& i# c4 s f3. 调整 LDA 的 Batch 大小 - c( M4 d. _8 s1 t为了得到主题中最重要的主题词,语料可以被分为固定大小的 batch,在这些 batch 上运行 LDA 模型会提供不同的结果,但是最佳的主题词会在这些 batch 上有交集。 8 d: [: {6 G+ [5 _/ W$ R) A 2 }/ N( v% C+ @2 E主题模型用于特征选择$ b; z* f ~" x( q
比如说文本分类任务中,LDA 可以用来选择特征,因为训练数据中含有类别信息,可以在不同类别的结果中,删除相同的、比较常见的主题词,为主题类别提供更好的特征。 # X2 z& W U: I1 d/ W1 a0 m/ T& g/ [8 E# S5 Q! Z# o1 N
结语& n4 t& v' [: G+ S! m a
本文主要参考了[1],没有什么公式,用于对 LDA 有一个大概的了解,后面也会更深入 LDA 模型,可以一边运行上面的代码一边感受 LDA 的作用。7 R3 t- W& C0 R2 X, I: Z+ E
3 _" @. {+ \# F( i( a1 `
参考文献 ]/ c0 v2 J. q9 N/ X) q9 K q[1] https://www.analyticsvidhya.com/blog/2016/08/beginners-guide-to-topic-modeling-in-python* }* j, r5 z. g: `- |1 |, G! j
) I1 e F/ y3 s0 o) K) u0 e$ J+ B[2] http://link.springer.com/chapter/10.1007%2F978-3-642-13657-3_43" \; ~ g0 \7 z7 ], Q7 M3 m5 U u
————————————————' u& d- m0 _% {
版权声明:本文为CSDN博主「情怀丶」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。: Q) d9 m3 G" ]: o+ X
原文链接:https://blog.csdn.net/selinda001/article/details/80446766 4 Z8 W4 h; x# F+ E2 T 8 w/ s0 D; d0 d; i( h; Y . |- A! ]8 e+ Q2 s8 T5 S. D