【问题标题】:Inference Labeled LDA/pLDA [Topic Modelling Toolbox]推理标记 LDA/pLDA [主题建模工具箱]
【发布时间】:2012-07-26 19:36:08
【问题描述】:

我一直在尝试使用 TMT 工具箱(stanford nlp 组)从经过训练的标记 LDA 模型和 pLDA 推断代码。 我浏览了以下链接中提供的示例: http://nlp.stanford.edu/software/tmt/tmt-0.3/ http://nlp.stanford.edu/software/tmt/tmt-0.4/

这是我正在尝试标记 LDA 推理的代码

val modelPath = file("llda-cvb0-59ea15c7-31-61406081-75faccf7");

val model = LoadCVB0LabeledLDA(modelPath);`

val source = CSVFile("pubmed-oa-subset.csv") ~> IDColumn(1);

val text = {
  source ~>                              // read from the source file
  Column(4) ~>                           // select column containing text
  TokenizeWith(model.tokenizer.get)      //tokenize with model's tokenizer
 }

 val labels = {
  source ~>                              // read from the source file
  Column(2) ~>                           // take column two, the year
  TokenizeWith(WhitespaceTokenizer())     
 }

 val outputPath = file(modelPath, source.meta[java.io.File].getName.replaceAll(".csv",""));

 val dataset = LabeledLDADataset(text,labels,model.termIndex,model.topicIndex);

 val perDocTopicDistributions =  InferCVB0LabeledLDADocumentTopicDistributions(model, dataset);

 val perDocTermTopicDistributions =EstimateLabeledLDAPerWordTopicDistributions(model, dataset, perDocTopicDistributions);

 TSVFile(outputPath+"-word-topic-distributions.tsv").write({
  for ((terms,(dId,dists)) <- text.iterator zip perDocTermTopicDistributions.iterator) yield {
    require(terms.id == dId);
    (terms.id,
     for ((term,dist) <- (terms.value zip dists)) yield {
       term + " " + dist.activeIterator.map({
         case (topic,prob) => model.topicIndex.get.get(topic) + ":" + prob
       }).mkString(" ");
     });
  }
});

错误

found : scalanlp.collection.LazyIterable[(String, Array[Double])] required: Iterable[(String, scalala.collection.sparse.SparseArray[Double])] EstimateLabeledLDAPerWordTopicDistributions(model, dataset, perDocTopicDistributions);

我知道这是类型不匹配错误。但我不知道如何为scala解决这个问题。 基本上我不明白我应该如何提取 1. 每个文档主题分布 2. infer 命令输出后的每个 doc 标签分布。

请帮忙。 在 pLDA 的情况下也是如此。 我到达了推理命令,然后不知如何处理它。

【问题讨论】:

    标签: scala nlp stanford-nlp lda topic-modeling


    【解决方案1】:

    Scala 类型系统比 Java 类型系统复杂得多,理解它将使您成为更好的程序员。问题出在这里:

    val perDocTermTopicDistributions =EstimateLabeledLDAPerWordTopicDistributions(model, dataset, perDocTopicDistributions);
    

    因为模型、数据集或 perDocTopicDistributions 属于以下类型:

    scalanlp.collection.LazyIterable[(String, Array[Double])]
    

    而 EstimateLabeledLDAPerWordTopicDistributions.apply 需要一个

    Iterable[(String, scalala.collection.sparse.SparseArray[Double])]
    

    调查这种类型错误的最好方法是查看 ScalaDoc(例如 tmt 的那个:http://nlp.stanford.edu/software/tmt/tmt-0.4/api/#package),如果你不能轻易找出问题所在,你应该明确你的类型代码中的变量如下所示:

     val perDocTopicDistributions:LazyIterable[(String, Array[Double])] =  InferCVB0LabeledLDADocumentTopicDistributions(model, dataset)
    

    如果我们一起看 edu.stanford.nlp.tmt.stage 的 javadoc:

    def
    EstimateLabeledLDAPerWordTopicDistributions (model: edu.stanford.nlp.tmt.model.llda.LabeledLDA[_, _, _], dataset: Iterable[LabeledLDADocumentParams], perDocTopicDistributions: Iterable[(String, SparseArray[Double])]): LazyIterable[(String, Array[SparseArray[Double]])]
    
    def
    InferCVB0LabeledLDADocumentTopicDistributions (model: CVB0LabeledLDA, dataset: Iterable[LabeledLDADocumentParams]): LazyIterable[(String, Array[Double])]
    

    现在您应该清楚 InferCVB0LabeledLDADocumentTopicDistributions 的返回不能直接用于馈送 EstimateLabeledLDAPerWordTopicDistributions。

    我从未使用过 stanford nlp,但这是设计使然 api 的工作原理,因此您只需在调用函数之前将 scalanlp.collection.LazyIterable[(String, Array[Double])] 转换为 Iterable[(String, scalala.collection.sparse.SparseArray[Double])]

    如果您查看有关如何进行此转换的 scaladoc,这非常简单。在 package 阶段,在 package.scala 我可以阅读import scalanlp.collection.LazyIterable;

    所以我知道去哪里看,实际上在 http://www.scalanlp.org/docs/core/data/#scalanlp.collection.LazyIterable 内部你有一个 toIterable 方法,可以将 LazyIterable 转换为 Iterable,但你仍然必须将内部数组转换为 SparseArray

    再次,我查看了 tmt 中 stage 包的 package.scala,我看到:import scalala.collection.sparse.SparseArray; 我寻找 scalala 文档:

    http://www.scalanlp.org/docs/scalala/0.4.1-SNAPSHOT/#scalala.collection.sparse.SparseArray

    事实证明,构造函数对我来说似乎很复杂,所以听起来很像我必须查看工厂方法的伴随对象。原来我要找的方法就在那里,它在Scala中像往常一样被称为apply。

    def
    apply [T] (values: T*)(implicit arg0: ClassManifest[T], arg1: DefaultArrayValue[T]): SparseArray[T]
    

    通过使用它,您可以编写具有以下签名的函数:

    def f: Array[Double] => SparseArray[Double]
    

    完成此操作后,您可以使用一行代码将 InferCVB0LabeledLDADocumentTopicDistributions 的结果转换为稀疏数组的非延迟迭代:

    result.toIterable.map { case (name, values => (name, f(values)) }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-04-30
      • 2014-05-10
      • 2018-03-01
      • 1970-01-01
      • 2019-06-09
      • 1970-01-01
      • 2016-02-27
      相关资源
      最近更新 更多