3

TMTツールボックス(スタンフォード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で解決する方法がわかりません。基本的に、infer コマンドの出力後に 1. ドキュメントごとのトピックの分布 2. ドキュメントごとのラベルの分布を抽出する方法がわかりません。

助けてください。pLDAの場合も同様です。私は推論コマンドに到達し、その後それをどうするかわかりません。

4

1 に答える 1

5

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 をフィードできないことは明らかです。

私はスタンフォードnlpを使用したことはありませんが、これはAPIの仕組みによるものであるため、関数を呼び出す前にscalanlp.collection.LazyIterable[(String, Array[Double])]変換するだけで済みます。Iterable[(String, scalala.collection.sparse.SparseArray[Double])]

この変換を行う方法について scaladoc を見ると、非常に簡単です。パッケージ ステージ内で、package.scala を読み取ることができます import scalanlp.collection.LazyIterable;

だから私はどこを見ればいいのか知っています内部配列を SparseArray に変換します

もう一度、tmt 内のステージ パッケージの 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]

これが完了すると、1 行のコードで、InferCVB0LabeledLDADocumentTopicDistributions の結果をスパース配列の遅延のない iterable に変えることができます。

result.toIterable.map { case (name, values => (name, f(values)) }
于 2012-08-03T09:57:20.083 に答える