在Mallet中按主题p(w | t)分配单词

时间:2016-05-27 21:26:12

标签: java nlp topic-modeling mallet

我需要在Java中找到Mallet找到的每个主题的单词分布(而不是how to get a probability distribution for a topic in mallet?中提到的CLI中)。我的意思是:Introduction to Latent Dirichlet Allocation

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)

Mallet为每个主题提供令牌“权重”,在http://comments.gmane.org/gmane.comp.ai.mallet.devel/2064中,有人试图编写一种方法来获取Mallet每个主题的单词分布。

我修改了方法,以便所有权重除以它们的总和,如上面的邮件列表中所讨论的那样。

以下方法(添加到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 个答案:

答案 0 :(得分:1)

这看起来会起作用,但我对风格有一些评论。

我并不是因使用double数组来表示主题/权重对而感到沮丧。如果您要遍历所有类型,为什么不使用类型为索引的密集double[]数组?如果您需要在此方法之外的其他方法中对条目进行排序,ArrayList可能有意义,但非标准化的中间ArrayList似乎很浪费。

第二个求和循环似乎没必要。您可以先将sum初始化为numTypes * beta,然后仅在遇到非零计数类型时添加weight - beta

如果定义normalizer = 1.0/sum然后在规范化循环中乘以而不是除以,它通常会产生明显的差异。