Вывод, помеченный LDA/pLDA [Topic Modeling Toolbox]

Я пытался выполнить код для вывода из обученной помеченной модели LDA и pLDA с использованием набора инструментов TMT (группа Stanford nlp). Я просмотрел примеры, представленные по следующим ссылкам: 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.

Пожалуйста помоги. То же самое и в случае с pLDA. Я добираюсь до команды вывода и после этого понятия не имею, что с ней делать.


person Rohit Jain    schedule 28.07.2012    source источник


Ответы (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)

Если мы посмотрим вместе на javadoc edu.stanford.nlp.tmt.stage:

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.scala я могу прочитать import scalanlp.collection.LazyIterable;

Так что я знаю, где искать, и на самом деле внутри http://www.scalanlp.org/docs/core/data/#scalanlp.collection.LazyIterable у вас есть метод toIterable, который превращает LazyIterable в Iterable, но вам все равно нужно преобразовать свой внутренний массив в SparseArray

Опять же, я смотрю в package.scala для пакета stage внутри tmt и вижу: import scalala.collection.sparse.SparseArray; И я ищу документацию по scalala:

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

Оказывается, конструкторы кажутся мне сложными, так что это звучит очень похоже на то, что мне придется заглянуть в объект-компаньон для фабричного метода. Оказывается, метод, который я ищу, есть, и он называется apply, как обычно в Scala.

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)) }
person Edmondo1984    schedule 03.08.2012