Иерархический процесс Дирихле gensim номер темы независимо от размера корпуса

Я использую модуль gensim HDP для набора документов.

>>> hdp = models.HdpModel(corpusB, id2word=dictionaryB)
>>> topics = hdp.print_topics(topics=-1, topn=20)
>>> len(topics)
150
>>> hdp = models.HdpModel(corpusA, id2word=dictionaryA)
>>> topics = hdp.print_topics(topics=-1, topn=20)
>>> len(topics)
150
>>> len(corpusA)
1113
>>> len(corpusB)
17

почему количество тем не зависит от длины корпуса?

5 ответов


@user3907335 здесь точно правильно: HDP вычислит столько тем, сколько назначено уровня усечения. , может быть, многие из этих тем имеют в основном нулевую вероятность возникновения. Чтобы помочь в этом в моей собственной работе, я написал удобную небольшую функцию, которая выполняет грубую оценку веса вероятности, связанного с каждой темой. Обратите внимание, что это только грубая метрика:он не учитывает вероятность, связанная с каждым слово. Тем не менее, он предоставляет довольно хорошую метрику, для которой темы значимы, а которые нет:

import pandas as pd
import numpy as np 

def topic_prob_extractor(hdp=None, topn=None):
    topic_list = hdp.show_topics(topics=-1, topn=topn)
    topics = [int(x.split(':')[0].split(' ')[1]) for x in topic_list]
    split_list = [x.split(' ') for x in topic_list]
    weights = []
    for lst in split_list:
        sub_list = []
        for entry in lst: 
            if '*' in entry: 
                sub_list.append(float(entry.split('*')[0]))
        weights.append(np.asarray(sub_list))
    sums = [np.sum(x) for x in weights]
    return pd.DataFrame({'topic_id' : topics, 'weight' : sums})

Я предполагаю, что вы уже знаете, как вычислить модель HDP. Как только у вас есть модель hdp, рассчитанная gensim, вы вызываете функцию следующим образом:

topic_weights = topic_prob_extractor(hdp, 500)

@ aaron's код выше нарушен из-за gensim изменения API. Я переписал и упростил его следующим образом. Работает с июня 2017 года с gensim П2.1.0

import pandas as pd

def topic_prob_extractor(gensim_hdp):
    shown_topics = gensim_hdp.show_topics(num_topics=-1, formatted=False)
    topics_nos = [x[0] for x in shown_topics ]
    weights = [ sum([item[1] for item in shown_topics[topicN][1]]) for topicN in topics_nos ]

    return pd.DataFrame({'topic_id' : topics_nos, 'weight' : weights})

Я не использовал gensim для HDPs, но возможно ли, что большинство тем в меньшем корпусе имеют чрезвычайно низкую вероятность возникновения ? Можете ли вы попробовать распечатать тему вероятности? Возможно, длина массива тем не обязательно означает, что все эти темы были фактически найдены в корпусе.


Я думаю, вы неправильно поняли операцию, выполняемую вызываемым методом. Непосредственно из документации вы можете увидеть:

псевдоним для show_topics (), который печатает верхние n наиболее вероятных слов для тем количество тем для журнала. Установите topics=-1 для печати всех тем.

вы обучили модель без указания уровня усечения по количеству тем, а по умолчанию 150. Вызываю print_topics с topics=-1 вы получите 20 лучших слов для каждой темы в вашем случае 150 тем.

Я еще новичок в библиотеке, так что, возможно, я ошибаюсь


подходы@Aron и @Roko Mijic игнорируют тот факт, что функция show_topics возвращает по умолчанию только верхние 20 слов каждой темы. Если вернуть все слова, составляющие тему, то все приближенные вероятности темы в этом случае будут равны 1 (или 0,999999). Я экспериментировал со следующим кодом, который является адаптацией @Roko Mijic:

def topic_prob_extractor(gensim_hdp, t=-1, w=25, isSorted=True):
    """
    Input the gensim model to get the rough topics' probabilities
    """
    shown_topics = gensim_hdp.show_topics(num_topics=t, num_words=w ,formatted=False)
    topics_nos = [x[0] for x in shown_topics ]
    weights = [ sum([item[1] for item in shown_topics[topicN][1]]) for topicN in topics_nos ]
    if (isSorted):
        return pd.DataFrame({'topic_id' : topics_nos, 'weight' : weights}).sort_values(by = "weight", ascending=False);
    else:
        return pd.DataFrame({'topic_id' : topics_nos, 'weight' : weights});

лучше, но я не уверен, что 100% действительно, подход является одним из упомянутых здесь. Вы можно получить истинные веса тем (альфа-вектор) модели HDP как:

alpha = hdpModel.hdp_to_lda()[0];

изучение эквивалентных Альфа-значений тем более логично, чем подсчет Весов первых 20 слов каждой темы, чтобы приблизить ее вероятность использования в данных.