赞
踩
1)从狄利克雷分布α中抽样,生成文档d的主题分布θ
2)从主题的多项式分布θ中抽样,生成文档d的第i个词的主题zi
3)从狄利克雷分布β中抽样,生成主题zi对应的词语分布φi
4)从词语的多项式分布φi中采样,最终生成词语wi
这个模型图的解释如下:
1.:这个过程表示生成第n个词对应的topic。在生成第m篇文档的时候,先从topic骰子中抽了一个骰子,然后投掷这个骰子,得到文档中第n个词的topic编号
2.:这个过程表示生成文档中的第n个词。在手里的K个word骰子中,选编号为的那个骰子进行投掷,生成
这里需要提一下狄利克雷分布的问题:对于一个3维狄利克雷参数向量(α, α, α)来说,当α小于1时,生成的概率向量偏向于某几维,值越小,偏得越厉害;当α大于1时,生成的概率向量倾向于中间,值越大,趋中越厉害。
经过一堆的数学推导之后,最后的形式是这个样子的:
其中的α和β就是狄利克雷分布的两个参数,K是语料中的topic数,是个超参,M是语料集中的文档数,,其中表示第k个topic产生的词中word t的个数。
得到了p(w,z)这个干净的表达式之后,就可以用gibbs sampling算法对这个分布进行采样。为什么要进行采样呢?当我们在面对一个未知或者复杂的分布时,积分、期望或者说联合分布很难算出来,是个NP难问题,但是条件概率很容易算出来,这时候就要进行采样。采样的目的是得到这个分布的样本,通过这些样本明确出该分布的具体结构,常用MCMC来进行分布采样。MCMC本身解决的是无法直接采样或理解的分布问题的,不是对已知分布进行采样。gibbs是对MCMC的一种改进。在LDA中,后验概率无法直接获得,我们通过gibbs采样的方法去采样该分布,从而得到模型结构。
我们现在需要求的是p(z|w),需要采样的也是p(z|w)这个分布,就是求某个单词应该属于什么topic。gibbs采样采的是(w, z),即联合分布的样本。收敛后在联合分布的样本空间,统计出各个参数。LDA是个生成模型,但是直接求联合分布概率,分母计算量比较大,只能通过gibbs采样,采样出联合分布的样本,执行多次之后产生的样本服从真实样本的分布,然后在联合样本空间计算出统计特性。gibbs采样做LDA的好处是简单,速度快,收敛结果也不错。
以上就是整个LDA的大致过程,通俗版以及公式版。简而言之,pLSA贝叶斯化就变成了LDA,对LDA模型进行改进有很多种方式,LDA的非参数化就变成了HDP(这个模型的优点就是自动确定topic的个数)
spark 代码:
- //屏蔽日志
- Logger.getLogger("org.apache.spark").setLevel(Level.ERROR)
- Logger.getLogger("org.eclipse.jetty.server").setLevel(Level.OFF)
-
- val warehouseLocation = "/Java/Spark/spark-warehouse"
- val spark=SparkSession
- .builder()
- .appName("myClusters")
- .master("local[4]")
- .config("spark.sql.warehouse.dir",warehouseLocation)
- .getOrCreate();
-
- val dataset_lpa=spark.read.format("libsvm")
- .load("/spark-2.0.0-bin-hadoop2.6/data/mllib/sample_lda_libsvm_data.txt")
- //------------------------------------1 模型训练-----------------------------------------
- /**
- * k: 主题数,或者聚类中心数
- * DocConcentration:文章分布的超参数(Dirichlet分布的参数),必需>1.0,值越大,推断出的分布越平滑
- * TopicConcentration:主题分布的超参数(Dirichlet分布的参数),必需>1.0,值越大,推断出的分布越平滑
- * MaxIterations:迭代次数,需充分迭代,至少20次以上
- * setSeed:随机种子
- * CheckpointInterval:迭代计算时检查点的间隔
- * Optimizer:优化计算方法,目前支持"em", "online" ,em方法更占内存,迭代次数多内存可能不够会抛出stack异常
- */
- val lda=new LDA()
- .setK(3)
- .setTopicConcentration(3)
- .setDocConcentration(3)
- .setOptimizer("online")
- .setCheckpointInterval(10)
- .setMaxIter(100)
-
- val model=lda.fit(dataset_lpa)
-
- /**生成的model不仅存储了推断的主题,还包括模型的评价方法。*/
- //---------------------------------2 模型评价-------------------------------------
-
- //模型的评价指标:ogLikelihood,logPerplexity
- //(1)根据训练集的模型分布计算的log likelihood,越大越好。
- val ll = model.logLikelihood(dataset_lpa)
-
- //(2)Perplexity评估,越小越好
- val lp = model.logPerplexity(dataset_lpa)
-
- println(s"The lower bound on the log likelihood of the entire corpus: $ll")
- println(s"The upper bound bound on perplexity: $lp")
-
- //---------------------------------3 模型及描述------------------------------
- //模型通过describeTopics、topicsMatrix来描述
-
- //(1)描述各个主题最终的前maxTermsPerTopic个词语(最重要的词向量)及其权重
- val topics=model.describeTopics(maxTermsPerTopic=2)
- println("The topics described by their top-weighted terms:")
- topics.show(false)
-
-
- /**主题 主题包含最重要的词语序号 各词语的权重
- +-----+-------------+------------------------------------------+
- |topic|termIndices |termWeights |
- +-----+-------------+------------------------------------------+
- |0 |[5, 4, 0, 1] |[0.21169509638828377, 0.19142090510443274]|
- |1 |[5, 6, 1, 2] |[0.12521929515791688, 0.10175547561034966]|
- |2 |[3, 10, 6, 9]|[0.19885345685860667, 0.18794498802657686]|
- +-----+-------------+------------------------------------------+
- */
-
- //(2) topicsMatrix: 主题-词分布,相当于phi。
- val topicsMat=model.topicsMatrix
- println("topicsMatrix")
- println(topicsMat.toString())
- /**topicsMatrix
- 12.992380082908886 0.5654447550856024 16.438154549631257
- 10.552480038361052 0.6367807085306598 19.81281695100224
- 2.204054885551135 0.597153999004713 6.979803589429554
- *
- */
-
- //-----------------------------------4 对语料的主题进行聚类---------------------
- val topicsProb=model.transform(dataset_lpa)
- topicsProb.select("label", "topicDistribution")show(false)
-
- /** label是文档序号 文档中各主题的权重
- +-----+--------------------------------------------------------------+
- |label|topicDistribution |
- +-----+--------------------------------------------------------------+
- |0.0 |[0.523730754859981,0.006564444943344147,0.46970480019667477] |
- |1.0 |[0.7825074858166653,0.011001204994496623,0.206491309188838] |
- |2.0 |[0.2085069748527087,0.005698459472719417,0.785794565674572] |
- ...
- */
-
- spark.stop()
Dirichlet分布的参数α、β
docConcentration(Dirichlet分布的参数α)
topicConcentration(Dirichlet分布的参数β)
首先要强调的是EM和Online两种算法,上述两个参数的设置是完全不同的。
EM方法:
(1)docConcentration: 只支持对称先验,K维向量的值都相同,必须>1.0。向量-1表示默认,k维向量值为(50/k)+1。
(2)topicConcentration: 只支持对称先验,值必须>1.0。向量-1表示默认。
docConcentration: Only symmetric priors are supported, so all values in the provided k-dimensional vector must be identical. All values must also be >1.0. Providing Vector(-1) results in default behavior (uniform k dimensional vector with value (50/k)+1
topicConcentration: Only symmetric priors supported. Values must be >1.0. Providing -1 results in defaulting to a value of 0.1+1.
由于这些参数都有明确的设置规则,因此也就不存在调优的问题了,计算出一个固定的值就可以了
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。