mou*_*hio 2 scala lda apache-spark
给定一个训练语料库docsWithFeatures,我在 Spark(通过 Scala API)中训练了一个 LDA 模型,如下所示:
import org.apache.spark.mllib.clustering.{LDA, DistributedLDAModel, LocalLDAModel}
val n_topics = 10;
val lda = new LDA().setK(n_topics).setMaxIterations(20)
val ldaModel = lda.run(docsWithFeatures)
val distLDAModel = ldaModel.asInstanceOf[DistributedLDAModel]
Run Code Online (Sandbox Code Playgroud)
现在我想报告模型的对数似然和困惑度。
我可以像这样得到对数似然:
scala> distLDAModel.logLikelihood
res11: Double = -2600097.2875547716
Run Code Online (Sandbox Code Playgroud)
但这就是事情变得奇怪的地方。我也想要困惑,它只为本地模型实现,所以我运行:
val localModel = distLDAModel.toLocal
Run Code Online (Sandbox Code Playgroud)
这让我得到这样的(日志)困惑:
scala> localModel.logPerplexity(docsWithFeatures)
res14: Double = 0.36729132682898674
Run Code Online (Sandbox Code Playgroud)
但是局部模型也支持对数似然计算,我是这样运行的:
scala> localModel.logLikelihood(docsWithFeatures)
res15: Double = -3672913.268234148
Run Code Online (Sandbox Code Playgroud)
那么这里发生了什么?两个对数似然值不应该相同吗?分布式模型的文档说
“logLikelihood:给定推断主题和文档主题分布的训练语料库的对数似然”
而对于本地模型,它说:
“logLikelihood(documents):根据推断的主题计算提供的文档的下限。”
我想这些是不同的,但我不清楚如何或为什么。我应该使用哪一种?也就是说,给定训练文档,哪一个是模型的“真实”似然?
总结一下,两个主要问题:
1 - 两个对数似然值如何以及为什么不同,我应该使用哪个?
2 - 在报告困惑时,我认为我应该使用 的指数是否正确logPerplexity result?(但为什么模型会给出日志困惑而不是简单的困惑?我错过了什么吗?)
1) 这两个对数似然值不同,因为它们正在计算两个不同模型的对数似然。DistributedLDAModel正在有效地计算对数似然的模型,其中主题的参数和每个文档的混合权重是常数(正如我在另一篇文章中提到的,DistributedLDAModel本质上是正则化的 PLSI,尽管您还需要使用它logPrior来解释正则化),而LocalLDAModel认为每个文档的主题参数和混合权重是随机变量。所以在这种情况下LocalLDAModel您必须整合(边缘化)主题参数和文档混合权重以计算对数似然(这就是使变分近似/下界变得必要的原因,尽管即使没有近似,对数似然也不是相同,因为模型不同。)
至于你应该使用哪个,我的建议(不知道你最终想要做什么)是使用你最初训练的类(即DistributedLDAModel.)附带的对数似然方法。作为旁注,主要(仅?)我可以看到将 aDistributedLDAModel转换为LocalLDAModelvia 的原因toLocal是为了能够计算新的(未训练的)文档集的主题混合权重(有关更多信息,请参阅我在此线程上的帖子:Spark MLlib LDA,如何推断新的未见文档的主题分布?),该操作在DistributedLDAModel.
2) log-perplexity 只是负对数似然除以语料库中的标记数。如果您除以 log-perplexity,math.log(2.0)则结果值也可以解释为在给定模型的情况下对您的语料库(作为词袋)进行编码所需的每个令牌的近似位数。
| 归档时间: |
|
| 查看次数: |
2783 次 |
| 最近记录: |