web-dev-qa-db-ja.com

コーパスサイズに依存しない階層的DirichletプロセスGensimトピック番号

一連のドキュメントでGensimHDPモジュールを使用しています。

>>> 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

トピックの数がコーパスの長さに依存しないのはなぜですか?

14
user0

@ 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モデルの計算方法はすでにご存知だと思います。 gensimによって計算されたhdpモデルを取得したら、次のように関数を呼び出します。

topic_weights = topic_prob_extractor(hdp, 500)
4
Aaron

上記の@Aaronのコードは、gensim APIの変更により壊れています。次のように書き直して簡略化しました。 2017年6月の時点でgensim v2.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})
10
Roko Mijic

@Aronと@RokoMijicのアプローチは、関数 show_topics デフォルトでは、各トピックの上位20語のみが返されます。トピックを構成するすべての単語を返す場合、その場合のすべての近似トピック確率は1(または0.999999)になります。 @RokoMijicのコードを応用した次のコードを試してみました。

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語の重みを集計して、データでの使用の確率を概算するよりも論理的です。

4
Jabro Jacob

呼び出されたメソッドによって実行される操作を誤解したと思います。あなたが見ることができるドキュメントから直接:

ログに記録するトピックのトピック数の上位n個の最も可能性の高い単語を出力するshow_topics()のエイリアス。すべてのトピックを印刷するには、topics = -1に設定します。

トピック数の切り捨てレベルを指定せずにモデルをトレーニングしました。デフォルトは150です。print_topicstopics=-1で呼び出すと、各トピックの上位20語(この場合は150)が取得されます。トピック。

私はまだ図書館の初心者なので、多分私は間違っています

3
p_mesh

私はHDPにgensimを使用していませんが、小さなコーパスのトピックのほとんどが発生する可能性が非常に低い可能性はありますか?トピックの確率を印刷してみてください。たぶん、トピック配列の長さは、必ずしもそれらすべてのトピックが実際にコーパスで見つかったことを意味するわけではありません。

3
user3907335