% @# {9 C. D3 E主题数量:主题数量从语料中抽取得到,使用 Kullback Leibler Divergence Score 可以获取最好的主题数量。 ; O3 @/ Y4 T# E! {1 o' E. m , x5 ]+ I" Z. V& M" f8 c) }- l# r) i8 a主题词数:组成一个主题所需要的词的数量。这些词的数量通常根据需求得到,如果说需求是抽取特征或者关键词,那么主题词数比较少,如果是抽取概念或者论点,那么主题词数比较多。 " Y" K; g3 }- r! M" T; f$ X ) q( C& X1 L8 t5 r) D; j迭代次数:使得 LDA 算法收敛的最大迭代次数 ; o+ W, ~ S0 _! A/ B( j! n5 \
- t- i4 g n- B2 @# [
1 X! l" C0 h. t) w四、Running in Python & v: X: H7 b# g$ X7 j t! J" j准备文档集合 ) j0 C3 e' A( m, t ~doc1 = "Sugar is bad to consume. My sister likes to have sugar, but not my father." T8 a) L! ]1 @+ y+ Cdoc2 = "My father spends a lot of time driving my sister around to dance practice." 0 I! V- E% Y- [$ qdoc3 = "Doctors suggest that driving may cause increased stress and blood pressure." 2 E' E. x/ p1 W3 D$ xdoc4 = "Sometimes I feel pressure to perform well at school, but my father never seems to drive my sister to do better."* s& j K9 s9 K( R3 z( D
doc5 = "Health experts say that Sugar is not good for your lifestyle." 7 Q) W. [/ B& E6 l: A $ L6 v j/ \4 M# i& |7 l# 整合文档数据% W& I/ d, |# u: R% a
doc_complete = [doc1, doc2, doc3, doc4, doc5] ' A2 v. A% A- S0 ] . }9 p6 Y7 U& U- g数据清洗和预处理 ) z q) W1 i6 w0 w7 n ?: P数据清洗对于任何文本挖掘任务来说都非常重要,在这个任务中,移除标点符号,停用词和标准化语料库(Lemmatizer,对于英文,将词归元)。 / I0 O+ B, T' Z5 C4 X# U* g8 I: j% u/ Y3 @' g! B
from nltk import stopwords, |: l- e& L! p: L8 \
from nltk.stem.wordnet import WordNetLemmatizer Q9 w5 p0 l0 R$ D' l
import string# ]0 f# v- \1 ^; l- N, u( t
& p- S) e1 S$ z' j0 Bstop = set(stopwords.words('english')) W1 y( s7 L+ v( c5 R. M0 {) P
exclude = set(string.punctuation)4 g# \/ @0 @4 y5 G
lemma = WordNetLemmatizer() 2 r2 s7 ?" x% `, K ( C/ y- B( {6 ?/ J3 Q& W5 Edef clean(doc):; p- @3 V) W& W4 ?5 x8 M! h3 Q, ^4 w
stop_free = " ".join([i for i in doc.lower().split() if i not in stop])6 J: T/ O8 w0 j% S3 k# G0 x
punc_free = ''.join(ch for ch in stop_free if ch not in exclude) - p- F- I0 }/ J normalized = " ".join(lemma.lemmatize(word) for word in punc_free.split()) : s- Q) h$ l! q, z3 T return normalized4 M2 J! _: n- x
9 M: ?$ ]8 r9 \& _
doc_clean = [clean(doc).split() for doc in doc_complete] . i+ I% t8 J. D5 C4 I7 m- J " L" [& [ L& n7 W2 T& v准备 Document - Term 矩阵* u$ I- j5 b/ q
语料是由所有的文档组成的,要运行数学模型,将语料转化为矩阵来表达是比较好的方式。LDA 模型在整个 DT 矩阵中寻找重复的词语模式。Python 提供了许多很好的库来进行文本挖掘任务,“genism” 是处理文本数据比较好的库。下面的代码掩饰如何转换语料为 Document - Term 矩阵:* j# g8 }9 c( ~7 W
4 E. y" l, z' q, y+ ^4 k
import genism3 r6 {$ N2 [" j: ]
from gensim import corpora! Y0 S/ ~4 g. G; s
. R, J5 s1 o; J# k/ Z9 w- f) b% g
# 创建语料的词语词典,每个单独的词语都会被赋予一个索引 A; L% r( X1 Q% d0 D3 |dictionary = corpora.Dictionary(doc_clean)4 o# {* a5 D' z7 {- T* p: \# Z
& V# u v. N _5 K/ L: m
# 使用上面的词典,将转换文档列表(语料)变成 DT 矩阵 : R8 y4 `: Q( B' H# ]doc_term_matrix = [dictionary.doc2bow(doc) for doc in doc_clean] # C+ o5 `$ H) [5 u- l( y" W# g3 E5 U- d) G! R. f
构建 LDA 模型 1 ], l l) X% s1 C; \创建一个 LDA 对象,使用 DT 矩阵进行训练。训练需要上面的一些超参数,gensim 模块允许 LDA 模型从训练语料中进行估计,并且从新的文档中获得对主题分布的推断。 $ z) `8 q: U! q6 {3 D4 ]3 z R8 B% o; ~1 }# e# 使用 gensim 来创建 LDA 模型对象 3 T0 H; g* V5 e( b! ULda = genism.models.ldamodel.LdaModel& B0 P0 ^6 Z; C9 k
' l- C, q- Z) l( r9 `% e) d% M
# 在 DT 矩阵上运行和训练 LDA 模型 0 @& W, j3 e) y6 ^6 G" S6 Uldamodel = Lda(doc_term_matrix, num_topics=3, id2word = dictionary, passes=50) , T0 U' J p) a6 K( H% e i1 G* ]3 [! C# e B1 Y9 r4 s' _! {3 m
结果% O# b% q- Y7 q# f3 X: i) }
# 输出结果 1 b: Q1 ?( d* @1 N$ H- Cprint(ldamodel.print_topics(num_topics=3, num_words=3)) ) N- ^/ x5 u8 z/ S* S V! G, ^# ] Z; p2 T) Q
[- i7 i- w$ c. q ?! m
'0.168*health + 0.083*sugar + 0.072*bad,+ Z. l& k+ [3 m% C+ {
'0.061*consume + 0.050*drive + 0.050*sister,( i9 X3 D) p$ b# d; C0 e V) N
'0.049*pressur + 0.049*father + 0.049*sister : x, V- }' i7 s2 |0 ~- w- [( Q$ d]1 I' g) H) } ]8 o
每一行包含了主题词和主题词的权重,Topic 1 可以看作为“不良健康习惯”,Topic 3 可以看作 “家庭”。 ; n! u# l9 h. B* u" [6 \! a; g1 W; r7 C' I" d+ l
五、提高主题模型结果的一些方法* H4 ^5 ~+ @( N9 z$ ] o
主题模型的结果完全取决于特征在语料库中的表示,但是语料通常表示为比较稀疏的文档矩阵,因此减少矩阵的维度可以提升主题模型的结果。* e1 f- c. r/ t/ X