2016-05-27 3 views
2

Malletで見つかった各トピックの単語の分布をJavaで取得する必要があります(how to get a probability distribution for a topic in mallet?のCLIではなく)。 Introduction to Latent Dirichlet Allocation::私が何を意味するかの例についてはマレットのトピックp(w | t)の分布

Topic A: 30% broccoli, 15% bananas, 10% breakfast, 10% munching, … (at which point, you could interpret topic A to be about food) 
Topic B: 20% chinchillas, 20% kittens, 20% cute, 15% hamster, … (at which point, you could interpret topic B to be about cute animals) 

マレットは、トピックごとにトークン「重み」を提供し、http://comments.gmane.org/gmane.comp.ai.mallet.devel/2064誰かにマレットのためのトピックごとの単語の分布を取得するための方法を書き込もうとしました。

上記のメーリングリストで説明したように、すべての重みが合計で除算されるようにメソッドを変更しました。

次のメソッド(ParallelTopicModel.javaに追加されたとき)は、Malletのトピックp(w | t)あたりの単語の分布を正しく計算しますか?

/** 
* Get the normalized topic word weights (weights sum up to 1.0) 
* @param topic the topic 
* @return the normalized topic word weights (weights sum up to 1.0) 
*/ 
public ArrayList<double[]> getNormalizedTopicWordWeights(int topic) { 
    ArrayList<double[]> tokenWeights = new ArrayList<double[]>(); 
    for (int type = 0; type < numTypes; type++) { 
     int[] topicCounts = typeTopicCounts[type]; 
     double weight = beta; 
     int index = 0; 
     while (index < topicCounts.length && topicCounts[index] > 0) { 
      int currentTopic = topicCounts[index] & topicMask; 
      if (currentTopic == topic) { 
       weight += topicCounts[index] >> topicBits; 
       break; 
      } 
      index++; 
     } 
     double[] tokenAndWeight = { (double) type, weight }; 
     tokenWeights.add(tokenAndWeight); 
    } 
    // normalize 
    double sum = 0; 
    // get the sum 
    for (double[] tokenAndWeight : tokenWeights) { 
     sum += tokenAndWeight[1]; 
    } 
    // divide each element by the sum 
    ArrayList<double[]> normalizedTokenWeights = new ArrayList<double[]>(); 
    for (double[] tokenAndWeight : tokenWeights) { 
     tokenAndWeight[1] = tokenAndWeight[1]/sum; 
     normalizedTokenWeights.add(tokenAndWeight); 
    } 
    return normalizedTokenWeights; 
} 

答えて

1

これはうまくいくようですが、スタイルに関するコメントがあります。

doubleアレイを使用してトピック/ウェイトペアを表現するのは夢中ではありません。すべての型を反復処理している場合は、型をインデックスとして密な配列double[]を使用しないでください。この外の別のメソッドでエントリをソートする必要がある場合は、ArrayListが意味をなさないかもしれませんが、非正規化された中間のArrayListは無駄に見えます。

第2集計ループは不要です。最初にsumnumTypes * betaに初期化し、ゼロ以外のタイプにヒットした場合にのみweight - betaを追加することができます。

normalizer = 1.0/sumを定義し、正規化ループで除算するのではなく、乗算すると、目立った違いが生じることがよくあります。

関連する問題