! z* y6 |* g2 h* X/ f% y6 y" r' R4 F4 ]6 [6 S5 Y! {4 G# W+ G F
三、LDA 的参数 - Q. N- v: d* i. V; e( s! Bαα :表示 document-topic 密度, αα 越高,文档包含的主题更多,反之包含的主题更少 ! n5 N, A- C1 x+ q- h' @) u4 F6 Y' M9 ^( \% k
ββ :表示 topic-word 密度, ββ 越高,主题包含的单词更多,反之包含的单词更少" K+ @. t( H: a: w( V. J+ C
4 R* l n# z7 a4 \) ?% O主题数量:主题数量从语料中抽取得到,使用 Kullback Leibler Divergence Score 可以获取最好的主题数量。 Z/ u% O$ a. i- K
$ G% t2 M1 \$ P8 d* w* n2 `主题词数:组成一个主题所需要的词的数量。这些词的数量通常根据需求得到,如果说需求是抽取特征或者关键词,那么主题词数比较少,如果是抽取概念或者论点,那么主题词数比较多。 ; ]* y" f6 i, V9 I6 K # k! r1 r" x6 C$ u5 z迭代次数:使得 LDA 算法收敛的最大迭代次数 8 y5 s* U' u/ A c1 f" C" `' |4 a7 ?8 s0 e+ z* h0 _4 u
: \ x/ h1 F9 u/ @" S) K# V
* a$ s! {2 f# k' j3 {4 Z" T1 [9 D
四、Running in Python- d, _% H% _$ J- r6 m9 n h
准备文档集合5 z2 T" w# n, F
doc1 = "Sugar is bad to consume. My sister likes to have sugar, but not my father." 6 x& X; e5 ?3 Tdoc2 = "My father spends a lot of time driving my sister around to dance practice."; e/ g- t2 l* t: F! x7 Q! ~" G
doc3 = "Doctors suggest that driving may cause increased stress and blood pressure." 7 A( D9 a+ g: y/ R" Mdoc4 = "Sometimes I feel pressure to perform well at school, but my father never seems to drive my sister to do better."# U/ l0 v7 D' h$ C
doc5 = "Health experts say that Sugar is not good for your lifestyle." . R8 j# g& ~% a4 u6 n3 ~8 R+ |* A 8 e) j. `, v$ H- Q# 整合文档数据 ! k( O, j4 G Q; S, adoc_complete = [doc1, doc2, doc3, doc4, doc5]8 j. h2 T# F' y- Y1 S
& E6 r2 X8 j* ~) E; x6 {
数据清洗和预处理6 a: T+ N" R( ]1 [+ ^
数据清洗对于任何文本挖掘任务来说都非常重要,在这个任务中,移除标点符号,停用词和标准化语料库(Lemmatizer,对于英文,将词归元)。 . L9 E+ `/ R; F: Q& o2 ? - U: V0 K: g, r0 A, y) \from nltk import stopwords 9 O& E& S) ^' G# R7 k' Afrom nltk.stem.wordnet import WordNetLemmatizer $ j/ K! i! V" k0 y& B& Oimport string$ @( ?8 ^# l+ y) d& J) R
! Y, l& @0 {) l' @stop = set(stopwords.words('english')) " h l8 i6 O% V8 _7 sexclude = set(string.punctuation) - I% w" a- E- i* N1 _lemma = WordNetLemmatizer() 9 E( C5 K" [0 ~, Q) [' T: c6 o0 k |' m2 z. ~2 U
def clean(doc):8 B6 t: `6 X1 W. ~7 L5 z
stop_free = " ".join([i for i in doc.lower().split() if i not in stop]) + I2 ~& c4 _# a* H punc_free = ''.join(ch for ch in stop_free if ch not in exclude)9 d3 K% f* p; V2 `0 U8 `' S
normalized = " ".join(lemma.lemmatize(word) for word in punc_free.split()) . B0 m0 v3 B0 c6 b return normalized 6 G' U7 L! p [) t t6 @- h! N$ b) n$ ]' V7 r' g: t
doc_clean = [clean(doc).split() for doc in doc_complete]2 b6 z$ n4 t6 j I% P
2 w) m1 C1 x& {9 ~# X准备 Document - Term 矩阵 $ P5 s( ^8 t& B W7 _4 \% z/ S语料是由所有的文档组成的,要运行数学模型,将语料转化为矩阵来表达是比较好的方式。LDA 模型在整个 DT 矩阵中寻找重复的词语模式。Python 提供了许多很好的库来进行文本挖掘任务,“genism” 是处理文本数据比较好的库。下面的代码掩饰如何转换语料为 Document - Term 矩阵:- E& _4 L; ?/ `5 ~8 j5 {% j2 ^7 C
9 |5 N) ~$ W$ P* T4 y7 F
import genism& ]' K+ c0 Q2 `. g2 @" q& e+ H
from gensim import corpora ( t: ]" G+ ?$ h8 u5 B% @% a5 ?. s! j C- P5 ~& C) s
# 创建语料的词语词典,每个单独的词语都会被赋予一个索引 " h! N H; k4 U" p( [4 L+ c. z2 Sdictionary = corpora.Dictionary(doc_clean)6 `8 o+ x7 P& j0 M5 g4 @6 x
# X. _. ^& l' C8 {' s# 使用上面的词典,将转换文档列表(语料)变成 DT 矩阵* U; s: L3 ~: J1 p6 p# y
doc_term_matrix = [dictionary.doc2bow(doc) for doc in doc_clean] " ^0 G! {2 \" @' f3 ^" e* U, f! O/ L" q: F
构建 LDA 模型 # `, K8 X( s" s& ^6 i8 J+ \创建一个 LDA 对象,使用 DT 矩阵进行训练。训练需要上面的一些超参数,gensim 模块允许 LDA 模型从训练语料中进行估计,并且从新的文档中获得对主题分布的推断。. D4 O' o, e! k& W
% Z& T* f- v# n4 p; c% ^/ A/ A
# 使用 gensim 来创建 LDA 模型对象 ( N+ L3 D' `$ M) A# OLda = genism.models.ldamodel.LdaModel ' y A( E7 Q7 \+ v7 C* Q/ `: I* i. V# \* r0 E
# 在 DT 矩阵上运行和训练 LDA 模型7 ]5 W" C% l% o6 b; i7 Z. _, k9 b
ldamodel = Lda(doc_term_matrix, num_topics=3, id2word = dictionary, passes=50)2 ?. W( u/ Z' H) w
4 E) z9 ?1 ^0 i' m/ h
结果7 y/ M: G9 ]) }5 A! R! u
# 输出结果' w+ [/ V+ e- }! O
print(ldamodel.print_topics(num_topics=3, num_words=3)) # E }1 _5 W$ g) z : }9 y0 D2 l( M) Z[$ p [: v- f* a4 M
'0.168*health + 0.083*sugar + 0.072*bad,+ O2 @2 v' x$ H# X' W" C8 E
'0.061*consume + 0.050*drive + 0.050*sister, 2 |+ ?" T. Z: T6 [ '0.049*pressur + 0.049*father + 0.049*sister - E5 H+ r5 `8 s" Y] ! P4 E4 m* i. g. J每一行包含了主题词和主题词的权重,Topic 1 可以看作为“不良健康习惯”,Topic 3 可以看作 “家庭”。3 _! `. d+ d+ A$ T' }
; b* @4 o- q7 h" v. |: a, d# k( w
五、提高主题模型结果的一些方法 & }2 d% K8 s# e3 _! X- s% E( Q8 C主题模型的结果完全取决于特征在语料库中的表示,但是语料通常表示为比较稀疏的文档矩阵,因此减少矩阵的维度可以提升主题模型的结果。. X, b; u% `( |: I( [! r, e
- F" {9 k9 {" I) F1 {$ D
1. 根据词频调整稀疏矩阵 ' u J ~2 {% [- E根据频率来分布词,高频词更可能出现在结果中,低频词实际上是语料库中的弱特征,对于词频进行分析,可以决定什么频率的值应该被视为阈值。; }, G5 S6 Y8 e2 Z 3 A4 s/ g4 Z0 D) W) a& c% G9 k9 p2. 根据词性标注 (Part of Speech Tag) 调整稀疏矩阵 ; v" p, k$ A6 K比起频率特征,词性特征更关注于上下文的信息。主题模型尝试去映射相近的词作为主题,但是每个词在上下文上有可能重要性不同,比如说介词 “IN” 包含 “within”,“upon”, “except”,基数词 “CD” 包含:许多(many),若干(several),个把(a,few)等等,情态助动词 “MD” 包含 “may”,“must” 等等,这些词可能只是语言的支撑词,对实际意义影响不大,因此可以通过词性来消除这些词的影响。( S3 Q/ u. R: c- R% }9 ` ) C4 M4 B3 S/ Y" w
3. 调整 LDA 的 Batch 大小 % x7 F: t) F8 Q6 Q为了得到主题中最重要的主题词,语料可以被分为固定大小的 batch,在这些 batch 上运行 LDA 模型会提供不同的结果,但是最佳的主题词会在这些 batch 上有交集。 8 Z1 K7 R4 A9 ]& _4 Z ) Q4 X( t7 S( C% [: t9 Z主题模型用于特征选择 # {, `2 _- N# b. }( Q$ ?比如说文本分类任务中,LDA 可以用来选择特征,因为训练数据中含有类别信息,可以在不同类别的结果中,删除相同的、比较常见的主题词,为主题类别提供更好的特征。 ) D& l1 @. ?1 p% c* b f! P; }/ _) m2 T+ y( T
结语7 Q. W0 ^) t) q- q' o- W
本文主要参考了[1],没有什么公式,用于对 LDA 有一个大概的了解,后面也会更深入 LDA 模型,可以一边运行上面的代码一边感受 LDA 的作用。 , Y1 K, R1 w8 f# t% U! W J2 Y7 t* V% c, c
参考文献2 Q8 p& j/ L8 T7 R( t
[1] https://www.analyticsvidhya.com/blog/2016/08/beginners-guide-to-topic-modeling-in-python5 D7 C- y! _, p
7 Y; h5 H) J2 b
[2] http://link.springer.com/chapter/10.1007%2F978-3-642-13657-3_438 R+ Y9 J! R: W/ {( M
————————————————2 V. u+ c7 H; ^% h2 L
版权声明:本文为CSDN博主「情怀丶」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 8 _# |/ y; ]+ F3 T% v原文链接:https://blog.csdn.net/selinda001/article/details/80446766 8 F, f4 R4 j2 q2 ]9 r ! q5 V: ?+ K. o 0 D9 R8 y% U" s0 l+ K8 x6 S