鉴于培训语料库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]
现在我想报告模型的对数似然和困惑。
我可以像这样获得对数似然性:
scala> distLDAModel.logLikelihood
res11: Double = -2600097.2875547716
但这就是事情变得怪异的地方。我也想要一个只为本地模型实现的困惑,所以我运行:
val localModel = distLDAModel.toLocal
让我像这样得到(日志)困惑:
scala> localModel.logPerplexity(docsWithFeatures)
res14: Double = 0.36729132682898674
但是本地模型也支持对数似然计算,我这样运行:
scala> localModel.logLikelihood(docsWithFeatures)
res15: Double = -3672913.268234148
那么这里发生了什么?两个对数似然值不应该相同吗?分布式模型的文档说
“logLikelihood:根据推断的主题和文档主题分布,记录训练语料库的可能性”
而对于本地模型,它说:
“logLikelihood(documents):根据推断的主题计算所提供文档的下限。”
我猜这些是不同的,但我不清楚如何或为什么。我应该使用哪一个?也就是说,考虑到培训文件,哪一个是模型的“真实”可能性?
总结一下,有两个主要问题:
1 - 两个对数似然值如何以及为什么不同,我应该使用哪个?
2 - 在报告困惑时,我是否认为我应该使用logPerplexity result
的指数? (但为什么模型会给出日志困惑而不仅仅是简单的困惑?我错过了什么吗?)
答案 0 :(得分:3)
1)这两个对数似然值不同,因为它们计算两个不同模型的对数似然。 DistributedLDAModel
有效地计算了log-likelihood w.r.t.一个模型,其中主题的参数和每个文档的混合权重是常量(正如我在另一篇文章中提到的,DistributedLDAModel
基本上是正则化的PLSI,尽管你也需要使用logPrior
({1}}认为主题参数以及每个文档的混合权重是随机变量。因此,在LocalLDAModel
的情况下,您必须整合(边缘化)主题参数并记录混合权重,以便计算对数似然(这就是使得变分逼近/下界必要的原因,即使没有由于模型只是不同,因此对数似然的近似值可能不同。)
至于你应该使用哪一个,我的建议(不知道你最终想做什么)将使用附加到你最初训练的班级的对数似然法(即LocalLDAModel
。 )作为旁注,我可以看到通过DistributedLDAModel
将DistributedLDAModel
转换为LocalLDAModel
的主要(仅?)原因是为了计算新主题混合权重(非训练)文档集(有关此内容的详细信息,请参阅此帖子中的帖子:Spark MLlib LDA, how to infer the topics distribution of a new unseen document?),toLocal
中不支持(但可能)支持的操作。
2)log-perplexity只是负对数似然除以语料库中的令牌数。如果将log-perplexity除以DistributedLDAModel
,则结果值也可以解释为给定模型编码语料库(作为一个单词)所需的每个标记的近似位数。