我在一组文件的火花上运行LDA并观察到topicMatrix的值,它代表了术语的主题分布,大于1,如548.2201,685.2436,138.4013 ......这些值是什么意思?这些是分布的对数值还是其他东西。如何将这些值转换为概率分布值。 提前致谢。
答案 0 :(得分:4)
在两个模型中(即DistributedLDAModel
和LocalLDAMoel
)我相信topicsMatrix
方法会返回(大约有一些正则化,因为Dirichlet先于主题)预期的单词主题计数矩阵。要检查这一点,您可以使用该矩阵并总结所有列。生成的向量(长度为topic-count-size)应该大致等于单词count(在所有文档上)。在任何情况下,要获得主题(词典中单词的概率分布),您需要规范化列由topicsMatrix
返回的矩阵,以便每个总和为1。
我还没有完全测试过,但是这样的事情应该能够规范化topicsMatrix
返回的矩阵的列:
import breeze.linalg.{DenseVector => BDV}
import org.apache.spark.mllib.linalg._
def normalizeColumns(m: Matrix): DenseMatrix = {
val bm = Matrices.toBreeze(m).toDenseMatrix
val columnSums = BDV.zeros[Double](bm.cols).t
var i = bm.rows
while (i > 0) { i -= 1; columnSums += bm(i, ::) }
i = bm.cols
while (i > 0) { i -= 1; bm(::, i) /= columnSums(i) }
new DenseMatrix(bm.rows, bm.cols, bm.data)
}
答案 1 :(得分:0)
规范化纯scala
中的topicsMatrix返回的矩阵的列def formatSparkLDAWordOutput(wordTopMat: Matrix, wordMap: Map[Int, String]): scala.Predef.Map[String, Array[Double]] = {
// incoming word top matrix is in column-major order and the columns are unnormalized
val m = wordTopMat.numRows
val n = wordTopMat.numCols
val columnSums: Array[Double] = Range(0, n).map(j => (Range(0, m).map(i => wordTopMat(i, j)).sum)).toArray
val wordProbs: Seq[Array[Double]] = wordTopMat.transpose.toArray.grouped(n).toSeq
.map(unnormProbs => unnormProbs.zipWithIndex.map({ case (u, j) => u / columnSums(j) }))
wordProbs.zipWithIndex.map({ case (topicProbs, wordInd) => (wordMap(wordInd), topicProbs) }).toMap
}