6 l- l- |) `; R+ Z% ^5 w$ Q ' T# S0 p7 A/ u三、LDA 的参数& U' M2 k# j) H! z9 w
αα :表示 document-topic 密度, αα 越高,文档包含的主题更多,反之包含的主题更少7 d+ h( s$ B8 E
5 y& @6 F9 d. h. p1 m4 j/ w
ββ :表示 topic-word 密度, ββ 越高,主题包含的单词更多,反之包含的单词更少 ( V, X' m) l" [& W7 t# ]# Y( {3 x' j- D5 ]8 f. w6 e
主题数量:主题数量从语料中抽取得到,使用 Kullback Leibler Divergence Score 可以获取最好的主题数量。4 C* m, k& \/ [) g4 z
. R$ _" G3 i8 i& w+ z
主题词数:组成一个主题所需要的词的数量。这些词的数量通常根据需求得到,如果说需求是抽取特征或者关键词,那么主题词数比较少,如果是抽取概念或者论点,那么主题词数比较多。 N) B! ~ _& X& z: I% S7 y. M4 y9 V8 G; Z# @9 a1 L
迭代次数:使得 LDA 算法收敛的最大迭代次数. ^- h5 {" {: i- O n+ v
% ?% G4 u" {) G( P' L% A# e
! x v7 A% Z6 J5 Y# N- f" q1 n
- B/ M" C; T- j0 B% w
四、Running in Python# ]$ ?6 F5 P$ w4 S
准备文档集合) a! T( i, M2 O7 ^* v
doc1 = "Sugar is bad to consume. My sister likes to have sugar, but not my father."6 s% n* t3 p q* _+ f* z* L
doc2 = "My father spends a lot of time driving my sister around to dance practice."9 U# f1 A* X6 F; J2 p
doc3 = "Doctors suggest that driving may cause increased stress and blood pressure." 1 i+ @4 `: M% H5 D; Qdoc4 = "Sometimes I feel pressure to perform well at school, but my father never seems to drive my sister to do better."( n( ?3 U3 h8 n: g/ b7 M
doc5 = "Health experts say that Sugar is not good for your lifestyle." 4 p* N9 D$ G, ]0 P: |* T* R* E7 n$ y0 G" K1 n- ?
# 整合文档数据! C" ^. Q3 b! E
doc_complete = [doc1, doc2, doc3, doc4, doc5] " g2 l x9 s" l$ K0 T / b1 p* a2 |, {数据清洗和预处理 ; ^( p! c' F' c( A7 ~# ~数据清洗对于任何文本挖掘任务来说都非常重要,在这个任务中,移除标点符号,停用词和标准化语料库(Lemmatizer,对于英文,将词归元)。 5 m. z1 z! y) d; P" k # }! O3 D# @1 a" Q, V9 e$ i$ ffrom nltk import stopwords( d. x Z$ j, h+ J
from nltk.stem.wordnet import WordNetLemmatizer8 U. j! n4 n4 w% Z+ f/ X; n
import string 3 u: T1 K5 l% I9 W' S4 H2 S 9 N/ T" G( d* S8 d1 Hstop = set(stopwords.words('english'))5 B, D1 u7 [2 v/ C7 W+ h
exclude = set(string.punctuation) 9 @2 w+ [$ X: r! ^% vlemma = WordNetLemmatizer()6 ^) n6 r: U+ p% |% ?
" D! k" r, f P/ @% U" d) {8 M% B& c. fdef clean(doc): i9 B6 E. h7 H3 O
stop_free = " ".join([i for i in doc.lower().split() if i not in stop]) / ^; {) G; u: w5 ?" F. y! B punc_free = ''.join(ch for ch in stop_free if ch not in exclude) , p. r% C# @. ^' A$ n" d9 ~& n normalized = " ".join(lemma.lemmatize(word) for word in punc_free.split()) / c+ D9 z' E. a return normalized 6 p5 E4 a# b0 ?, v% ~" s2 e4 h4 I- W8 p. z3 D" W9 U8 F6 g5 b
doc_clean = [clean(doc).split() for doc in doc_complete] , |1 O7 X* @0 }- f% G# W : ^. ?6 @$ X( s8 d% a准备 Document - Term 矩阵+ S% ]" _/ Z! Y
语料是由所有的文档组成的,要运行数学模型,将语料转化为矩阵来表达是比较好的方式。LDA 模型在整个 DT 矩阵中寻找重复的词语模式。Python 提供了许多很好的库来进行文本挖掘任务,“genism” 是处理文本数据比较好的库。下面的代码掩饰如何转换语料为 Document - Term 矩阵: . c, Q3 ]- z: c7 R4 c3 m* }! d) A% R/ [/ f' z
import genism- w# q' Q+ ?- s* _# Z0 ]6 P$ }, L
from gensim import corpora + U( w9 z* b, _1 A* e* o l. R 2 F7 ?( h2 B4 f8 ~$ C2 ^# 创建语料的词语词典,每个单独的词语都会被赋予一个索引% i7 f. K z8 X) W7 ]
dictionary = corpora.Dictionary(doc_clean) + b+ R4 P5 A. C . c W1 O! h% ~" T6 k9 B7 j# 使用上面的词典,将转换文档列表(语料)变成 DT 矩阵 ; F0 k2 o6 ~* g3 N) i" @doc_term_matrix = [dictionary.doc2bow(doc) for doc in doc_clean] 6 G* ?; B) G! I9 t& [9 v 3 J1 [" p! f1 u* k! y+ f6 S n构建 LDA 模型 * I7 v8 A+ S' V' D创建一个 LDA 对象,使用 DT 矩阵进行训练。训练需要上面的一些超参数,gensim 模块允许 LDA 模型从训练语料中进行估计,并且从新的文档中获得对主题分布的推断。 0 Q; v5 D" m, [' z( v" m% _+ A/ }1 k) a& I
# 使用 gensim 来创建 LDA 模型对象 9 M, H$ [$ g% r( D2 c( QLda = genism.models.ldamodel.LdaModel# x. N' V) P8 I( I: P: p- V: S
- m. f% n6 |' o6 ~- H# 在 DT 矩阵上运行和训练 LDA 模型 4 |$ F$ h/ {! S' H: b% s6 j3 n( tldamodel = Lda(doc_term_matrix, num_topics=3, id2word = dictionary, passes=50) 3 `* K9 v6 Y( v! ], @! f, E ) c& }% |% m7 ]2 ]结果4 @4 J3 j; r) b3 O
# 输出结果% O5 V% X/ D7 I
print(ldamodel.print_topics(num_topics=3, num_words=3)); v: ~! s* J4 j, U$ T! k; F0 R
, [4 D+ O7 H+ h+ Z( Y' |
[ $ U9 {( m0 K/ S! Z c2 ^1 m9 O '0.168*health + 0.083*sugar + 0.072*bad, ; B2 f. P' P/ o) s5 {& o '0.061*consume + 0.050*drive + 0.050*sister, 4 X: e/ r% \+ L: c2 ^ '0.049*pressur + 0.049*father + 0.049*sister & I5 ]' ~$ `" u2 ]$ z6 _: f]! O. V$ j, e f5 a, T. M
每一行包含了主题词和主题词的权重,Topic 1 可以看作为“不良健康习惯”,Topic 3 可以看作 “家庭”。 + V' Y& I8 G7 z2 c+ F) M P$ R8 S! i7 P/ F; \
五、提高主题模型结果的一些方法" r. P- P2 a+ |" `. q& x5 n2 [8 R5 F
主题模型的结果完全取决于特征在语料库中的表示,但是语料通常表示为比较稀疏的文档矩阵,因此减少矩阵的维度可以提升主题模型的结果。 7 U5 |" x& r8 c( j/ o8 M3 O @# t C u3 F
1. 根据词频调整稀疏矩阵4 `$ Q8 C3 |7 L) t
根据频率来分布词,高频词更可能出现在结果中,低频词实际上是语料库中的弱特征,对于词频进行分析,可以决定什么频率的值应该被视为阈值。 1 \& f# C/ i& _2 \$ M$ F/ o3 U* Q0 O7 C. d& I9 p$ |: q
2. 根据词性标注 (Part of Speech Tag) 调整稀疏矩阵 , C3 L: b T. o! }: |& n比起频率特征,词性特征更关注于上下文的信息。主题模型尝试去映射相近的词作为主题,但是每个词在上下文上有可能重要性不同,比如说介词 “IN” 包含 “within”,“upon”, “except”,基数词 “CD” 包含:许多(many),若干(several),个把(a,few)等等,情态助动词 “MD” 包含 “may”,“must” 等等,这些词可能只是语言的支撑词,对实际意义影响不大,因此可以通过词性来消除这些词的影响。# P: Q$ f0 q" ^9 _8 c * @7 @5 z$ s" A {, K2 z3. 调整 LDA 的 Batch 大小# @) K8 R* @! z) V$ Y
为了得到主题中最重要的主题词,语料可以被分为固定大小的 batch,在这些 batch 上运行 LDA 模型会提供不同的结果,但是最佳的主题词会在这些 batch 上有交集。 % q0 ?4 X Y1 p9 R 5 p+ s4 [9 s9 z& }# N6 \) H( u& p; v主题模型用于特征选择 % Q3 Z: p. Y* I8 u比如说文本分类任务中,LDA 可以用来选择特征,因为训练数据中含有类别信息,可以在不同类别的结果中,删除相同的、比较常见的主题词,为主题类别提供更好的特征。 : M; b2 F4 ^3 E1 o" k, S* y* c* \9 }" W7 {+ ?( n2 r
结语 % D; ]8 b+ V$ ^- b本文主要参考了[1],没有什么公式,用于对 LDA 有一个大概的了解,后面也会更深入 LDA 模型,可以一边运行上面的代码一边感受 LDA 的作用。" g! y4 W# \( \! E) t% P
6 Z3 x$ j. W, k6 W7 B9 d. T! K& D参考文献 # Y u! O& Q2 n; E: m[1] https://www.analyticsvidhya.com/blog/2016/08/beginners-guide-to-topic-modeling-in-python3 k7 Z% L- T8 N% h) o
9 z- @( e% G7 P& \6 }0 g: _[2] http://link.springer.com/chapter/10.1007%2F978-3-642-13657-3_43/ T4 J: Y: O5 O9 K1 Z
———————————————— 4 K4 Q# T B G9 v+ G# h( O版权声明:本文为CSDN博主「情怀丶」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。2 y t, V* J7 b e2 t
原文链接:https://blog.csdn.net/selinda001/article/details/804467664 ^2 l- @% ^& R4 O8 _