【问题标题】:Interpretation of Spark MLLib LDA resultsSpark MLLib LDA 结果解读
【发布时间】:2016-01-24 15:55:52
【问题描述】:

我在 spark 上为一组文档运行 LDA,并观察到 ​​topicMatrix 的值(代表词项上的主题分布)大于 1,例如 548.2201、685.2436、138.4013... 这些值是什么意思?这些是分布的对数值还是什么。如何将这些值转换为概率分布值。 提前致谢。

【问题讨论】:

    标签: apache-spark lda apache-spark-mllib


    【解决方案1】:

    在这两种模型(即DistributedLDAModelLocalLDAMoel)中,我相信topicsMatrix 方法将返回(大约,由于Dirichlet 对主题的先验,有一些正则化)预期的词-主题计数矩阵.要检查这一点,您可以使用该矩阵并将所有列相加。结果向量(长度为主题计数大小)应该大约等于字数(在所有文档中)。无论如何,要获得主题(字典中单词的概率分布),您需要对列进行归一化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)
    } 
    

    【讨论】:

    • 感谢您的回复。但是是否有任何文件在任何地方提到这些事情?
    • 好的,非常感谢。我还想检查文档的主题分布。我正在尝试 ldamodel.topicdistribution() 但它表明它不是 spark 库的成员。你知道如何为经过训练的文档和新文档找到主题分布吗?
    • 我假设您正在使用更新的在线变分 EM 算法来拟合 LocalLDAModelLocalLDAModel 不保留训练集中每个文档的主题分布(尽管它确实保留了计算它所需的一切),因此不支持 topicDistributions 方法的无参数版本(与 DistributedLDAModel 不同.) 您可以使用ldaModel.topicDistributions(docs) 获取RDD 的文档(无论是在训练集中还是在训练集外)的主题分布。
    • 您可能会发现此讨论也很有用:stackoverflow.com/questions/32604516/…
    • topicdistribution 的输出类型为 Array[(Long, org.apache.spark.mllib.linalg.Vector)] ...知道如何将其导出到 scala 中的文件吗?跨度>
    【解决方案2】:

    在纯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
    
    }
    

    https://github.com/apache/incubator-spot/blob/v1.0-incubating/spot-ml/src/main/scala/org/apache/spot/lda/SpotLDAWrapper.scala#L237

    【讨论】:

      猜你喜欢
      • 2016-10-18
      • 2016-02-20
      • 2016-02-05
      • 2016-08-18
      • 2015-11-08
      • 2016-09-03
      • 2015-10-20
      • 2015-12-20
      • 2017-07-04
      相关资源
      最近更新 更多