7.2 LDA

7.2.1 LDA 简介

LDA(Latent Dirichlet Allocation),中文全称为隐含狄利克雷分布,最先由 Blei, David M. 等人于2003年提出,是一种以词、主题和文档三层贝叶斯概率为核心结构的主题模型。同时, LDA 也是一种无监督机器学习算法,我们在 LDA 模型训练前不需要进行任何手工标注。目前, LDA 在文本挖掘领域包括文本主题识别、文本分类以及文本相似度计算方面都有广泛应用。

在主题模型中,“主题”一词是一个相对抽象的概念,通常表现为一系列相关的词,以及这些词出现的条件概率。一个主题可以被理解为一个袋子,这个袋子有概率抖出一些词汇用于组成文档,我们可以通过这些词汇得知主题所要传达的语义。LDA 的核心目标便是告诉我们,在我们的语料集中一共出现了哪些主题,以及这些主题中每个词出现的概率是多少。

在 LDA 中,模型将文档生成的过程理解为先选定一个主题向量 θ ,并确定每个主题被选择的概率,然后在生成文档中每个单词的时候,从主题分布向量 θ 中选择一个主题 z ,按主题 z 的单词概率分布生成一个单词。对于一篇包含 N 个词汇的文档, LDA 模型的联合概率可表示为:

其中, $p(\theta|\alpha)$ 为文档被选定主题向量 $\theta$ 的概率,服从 Dirichlet 分布; $p(z_n|\theta)$ 为从主题向量 $\theta$ 中选择主题 $z_n$ 的概率,服从多项式分布;$p(w_n|z_n)$ 为从主题 z_n 中选择词汇 w_n 的概率,服从 Dirichlet 分布;α 和 β 则分别表示 LDA 中两个 Dirichlet 分布的分布参数,这两个参数属于语料级别,不会由于文档的不同而改变。

LDA 模型的生成过程也是对 Dirichlet 分布参数 α 和 β 的估计拟合过程,在实际应用中,计算机程序通常将通过 EM 算法来完成对 α 与 β 的参数值的估计,即在算法的 E-step 输入待定参数 α 和 β 的值,从而计算似然函数;之后在 M-step 最大化似然函数,解出对应的 α 和 β,不断迭代直至收敛。

LDA 模型在解决文本数据分析问题时的优势表现在其合理的概率层次以及相对直观的结果表现,一般情况下,我们能够直接从主题中包含的词直接观察得主题的含义,从而更容易地找到隐藏在文本之中的语义关联。在下文中,我们将介绍一系列工具库,帮助大家实现 LDA 模型的构建与应用。

7.2.2 利用 gensim 库训练 LDA 主题模型

gensim 库 models 包中的 ldamodel 模块中定义了 LdaModel 类及相关方法实现 LDA 主题模型,LdaModel 类的实例化方式为:实例=LdaModel(corpus=None, num_topics=100, id2word=None, distributed=False, chunksize=2000, passes=1, update_every=1, alpha='symmetric', eta=None, decay=0.5, offset=1.0, eval_every=10, iterations=50, gamma_threshold=0.001, minimum_probability=0.01, random_state=None, ns_conf={})

部分参数说明:

corpus:用该参数传入的文档语料将会被用来训练模型,如果不指定该参数,则不进行任何训练,默认后续会调用 update() 方法对模型语料进行更新

num_topics:需要提取的潜在主题数

id2word:用于设置构建模型的词典,决定了词汇数量

distributed:是否开启分布式计算

chunksize:文件块大小

alpha:决定文档主题狄利克雷先验分布的超参数,默认取值为对称 1.0/num_topics 先验,可以自行设置,也支持以下两种取值: (1)‘asymmetric’ :固定的非对称 1.0/topicno 先验
(2) ‘auto’:根据实际数据学习得到的非对称先验 eta:决定主题词汇狄利克雷先验分布的超参数,可以自行设置为对称的先验分布常量或者长度为词汇总数的向量作为非对称先验,此外也支持以下两种取值: (1)‘auto’:根据实际数据学习得到的非对称先验
(2)形如 num_topics x num_words 的矩阵:为每一个主题都引入一个词汇非对称先验分布

minimum_probability:用于限制返回一个文档主题的概率

相关方法及属性如下:

(1)get_document_topics 方法

get_document_topics 方法以(主题 id,主题概率)的形式返回指定文档的主题分布,调用方式为:get_document_topics(bow, minimum_probability=None, minimum_phi_value=None, per_word_topics=False)

参数说明:

bow:指定分析的文档

minimum_probability:忽略概率小于该参数值的主题

per_word_topics:取值为 True 时,同时按照可能性的降序返回词汇对应的主题

(2)get_term_topics 方法

get_term_topics 方法用于返回词典中指定词汇最有可能对应的主题,调用方式为:实例.get_term_topics(word_id, minimum_probability=None),其中参数 word_id 即为指定词汇 id ,minimum_probability 为返回主题的最小概率限定

(3)get_topic_terms 方法

get_topic_terms 方法以(词汇 id,概率)的形式返回指定主题的重要词汇,调用方式为:get_topic_terms(topicid, topn=10),参数 topicid 即为主题 id,topn 为返回的词汇数。

(4)show_topic 方法

show_topic 方法直接以(词汇,概率)的形式返回主题的重要词汇,调用方式为:show_topic(topicid, topn=10),其中参数 topicid 即为主题 id,topn 为返回的词汇数。

(5)show_topics 方法

show_topics 方法可以同时返回多个主题的重要词汇,调用方式为:show_topics(num_topics=10, num_words=10, log=False, formatted=True),需要注意的是,和上一节介绍的 LSI 不同,该方法返回的主题并未按照概率自动排序,而是随机抽取的,所以多次调用该方法可能会得到不同的结果

参数说明:

num_topics:返回的主题数,默认取值为 10

num_words:每个主题返回的词汇书,默认取值为 10

log:是否将得到的结果输出到日志中

formatted:取值为 True 时以字符串形式返回词汇及相应概率,取值为 False 时返回词汇和相应概率组成的元组

(6)“[]” 方法

“[]” 方法可以返回文档在各个主题的分布,调用方式为:实例[document]

例 3 仍然以两类新闻标题为例,利用 LDA 模型将语料映射到二维主题空间


In [5]:from gensim.models.ldamodel import LdaModel
       lda = LdaModel(corpus=corpus_tfidf,id2word=dictionary,num_topics=2)
       lda.show_topics(2)
Out[5]:[(0,
         u'0.032*"new" + 0.032*"open" + 0.031*"disperse" + 0.031*"alert" + 0.031*"innovation" + 0.031*"set" + 0.031*"red" + 0.031*"beijing" + 0.031*"university" + 0.030*"lifts"'),
        (1,
         u'0.034*"of" + 0.034*"source" + 0.034*"pollutant" + 0.033*"revealed" + 0.033*"major" + 0.032*"school" + 0.032*"players" + 0.031*"kung" + 0.030*"fu" + 0.030*"combines"')]
In [6]:lda.get_term_topics(1)
Out[6]:[(0, 0.014964645383614911)]
In [7]:for i in corpus_tfidf:
           print lda[i]
Out[7]:[(0, 0.82505037243004165), (1, 0.17494962756995844)]
       [(0, 0.16708784121775896), (1, 0.83291215878224101)]
       [(0, 0.80727070347450824), (1, 0.19272929652549178)]
       [(0, 0.82151361100587073), (1, 0.1784863889941293 )]
       [(0, 0.17230199161117327), (1, 0.82769800838882668)]

7.2.3 利用 sklearn 构建 LDA 模型

sklearn 库 decomposition 包也提供了 online_lda 模块构建 LDA 模型,主要利用其下定义的类 LatentDirichletAllocation 通过变分贝叶斯算法实现这一过程(官方文档 http://scikit-learn.org/dev/modules/decomposition.html#latentdirichletallocation)。该类的初始化方式为:实例=LatentDirichletAllocation(n_topics=10, doc_topic_prior=None, topic_word_prior=None, learning_method=None, learning_decay=0.7, learning_offset=10.0, max_iter=10, batch_size=128, evaluate_every=-1, total_samples=1000000.0, perp_tol=0.1, mean_change_tol=0.001, max_doc_update_iter=100, n_jobs=1, verbose=0, random_state=None)

部分参数说明:

n_topics:主题空间维度

doc_topic_prior:文档主题先验分布,对应文档中的参数 alpha,默认 None 值表示取值 1 / n_topics

topic_word_prior :主题词汇先验分布,对应文档中的参数 eta,默认 None 值表示取值 1 / n_topics

learning_method :模型的学习方法,取值为 ‘batch’ 或 ‘online’。一般情况下,当数据量比较大时,‘online’ 方法学习速度比较快。

learning_decay:该参数用于控制 ‘online’ 学习方法的学习率,取值范围应在(0.5, 1.0]以保证渐进收敛。当该参数取值为 0 并且参数“ batch_size”取值为 n_samples 时,等同于‘batch’学习方法,即文档中的 kappa。

learning_offset:该参数也会影响 ‘online’ 学习方法的学习率,会降低学习过程的迭代次数。

max_iter:最大迭代次数

total_samples:文档总数,仅当调用 partial_fit 方法时才需要设置

batch_size:‘online’ 学习方法每一次 EM 迭代的文档数

evaluate_every:在调用 fit 方法时设置困惑度(perplexity)评估的频率,困惑度一般在自然语言处理中用来衡量训练出的语言模型的好坏。困惑度评估一方面可以检查训练过程的收敛情况,但是也会增加训练时长,如果每次迭代都评估一次的话,训练时长可能会增加为原来的两倍。当该参数取值为 0 或负时,表示在训练过程中不评估困惑度,

mean_change_tol:EM 算法的 E 步中停止更新文档主题分布的临界值

max_doc_update_iter:EM 算法的 E 步中更新文档主题分布的最大迭代次数

相关方法及属性如下:

@补充方法属性列表

例 4 仍然以两类新闻标题为例,利用 LDA 模型将语料映射到二维主题空间


In [8]:from sklearn.decomposition import LatentDirichletAllocation
       lda = LatentDirichletAllocation(n_topics=2)
       # 利用 TfidfVectorizer 计算 TF-IDF 矩阵
       vectorizer = TfidfVectorizer()
       corpus_tfidf=vectorizer.fit_transform(title).toarray()
       # 构建二维语义空间
       lda = LatentDirichletAllocation(n_topics=2)
       lda.fit_transform(corpus_tfidf)
Out[8]:array([[ 3.29983659,  0.66251637],
              [ 0.66252396,  3.15163069],
              [ 0.62946368,  3.33981907],
              [ 3.30959033,  0.65276262],
              [ 3.26581911,  0.69936272]])

results matching ""

    No results matching ""