【问题标题】:probabilities returned by gensim's get_document_topics method doesn't add up to onegensim 的 get_document_topics 方法返回的概率不等于 1
【发布时间】:2017-11-18 04:34:15
【问题描述】:

有时它返回所有主题的概率,一切都很好,但有时它只返回几个主题的概率,它们加起来不等于一个,这似乎取决于文档。一般来说,当它返回的主题很少时,概率加起来或多或少 80%,那么它是否只返回最相关的主题?有没有办法强制它返回所有概率?

也许我遗漏了一些东西,但我找不到该方法参数的任何文档。

【问题讨论】:

    标签: text-mining gensim lda topic-modeling


    【解决方案1】:

    我遇到了同样的问题,并通过在调用gensim.models.ldamodel.LdaModel 对象的get_document_topics 方法时包含参数minimum_probability=0 来解决它。

        topic_assignments = lda.get_document_topics(corpus,minimum_probability=0)
    

    默认情况下,gensim 不会输出低于 0.01 的概率,因此特别是对于任何文档,如果有任何主题分配的概率低于此阈值,则该文档的主题概率之和不会相加最多一个。

    这是一个例子:

    from gensim.test.utils import common_texts
    from gensim.corpora.dictionary import Dictionary
    from gensim.models.ldamodel import LdaModel
    
    # Create a corpus from a list of texts
    common_dictionary = Dictionary(common_texts)
    common_corpus = [common_dictionary.doc2bow(text) for text in common_texts]
    
    # Train the model on the corpus.
    lda = LdaModel(common_corpus, num_topics=100)
    
    # Try values of minimum_probability argument of None (default) and 0
    for minimum_probability in (None, 0):
        # Get topic probabilites for each document
        topic_assignments = lda.get_document_topics(common_corpus,minimum_probability=minimum_probability)
        probabilities = [ [entry[1] for entry in doc] for doc in topic_assignments ]
        # Print output
        print(f"Calculating topic probabilities with minimum_probability argument = {str(minimum_probability)}")
        print(f"Sum of probabilites:")
        for i, P in enumerate(probabilities):
            sum_P = sum(P)
            print(f"\tdoc {i} = {sum_P}")
    

    输出将是:

    Calculating topic probabilities with minimum_probability argument = None
    Sum of probabilities:
        doc 0 = 0.6733324527740479
        doc 1 = 0.8585712909698486
        doc 2 = 0.7549994885921478
        doc 3 = 0.8019999265670776
        doc 4 = 0.7524996995925903
        doc 5 = 0
        doc 6 = 0
        doc 7 = 0
        doc 8 = 0.5049992203712463
    Calculating topic probabilities with minimum_probability argument = 0
    Sum of probabilites:
        doc 0 = 1.0000000400468707
        doc 1 = 1.0000000337604433
        doc 2 = 1.0000000079162419
        doc 3 = 1.0000000284053385
        doc 4 = 0.9999999937135726
        doc 5 = 0.9999999776482582
        doc 6 = 0.9999999776482582
        doc 7 = 0.9999999776482582
        doc 8 = 0.9999999930150807
    

    此默认行为在文档中并未明确说明。 get_document_topics 方法的 minimum_probability 的默认值为 None,但这不会将概率设置为零。而是将minimum_probability 的值设置为gensim.models.ldamodel.LdaModel 对象的minimum_probability 的值,默认情况下为0.01,如您在source code 中所见:

    def __init__(self, corpus=None, num_topics=100, id2word=None,
                 distributed=False, chunksize=2000, passes=1, update_every=1,
                 alpha='symmetric', eta=None, decay=0.5, offset=1.0, eval_every=10,
                 iterations=50, gamma_threshold=0.001, minimum_probability=0.01,
                 random_state=None, ns_conf=None, minimum_phi_value=0.01,
                 per_word_topics=False, callbacks=None, dtype=np.float32):
    

    【讨论】:

    • 问题是为什么当我们将minimum_probability 设置为0.01 时,对于某些文档,为文档的每个主题分配的概率总和会略高于1?例如,输出中doc0 中分配给每个主题的概率总和为1.0000000400468707,大于一。
    • 这个数字非常接近 1,差值几乎可以肯定是浮点算术舍入误差造成的。
    • 感谢您的快速回复,我可以使用get_document_topic 获取不在训练数据集中的文档的主题吗?
    • 可以,例如:test_texts = [['connected','graph'],['graphical','user','interface']] test_corpus = [common_dictionary.doc2bow(text) for text in test_texts] test_topic_assignments = lda.get_document_topics(test_corpus,minimum_probability=minimum_probability) test_probabilities = [ [entry[1] for entry in doc] for doc in test_topic_assignments ]
    【解决方案2】:

    我在从事 LDA 主题建模工作时偶然发现了这篇文章。我确实创建了两个主题,比如说 topic1 和 topic2。

    每个主题的前10个单词如下:0.009*"would" + 0.008*"experi" + 0.008*"need" + 0.007*"like" + 0.007*"code" + 0.007*"work" + 0.006*"think" + 0.006*"make" + 0.006*"one" + 0.006*"get

    0.027*"ierr" + 0.018*"line" + 0.014*"0.0e+00" + 0.010*"error" + 0.009*"defin" + 0.009*"norm" + 0.006*"call" + 0.005*"type" + 0.005*"de" + 0.005*"warn

    最终,我拿了 1 个文档来确定最近的主题。

    for d in doc:
        bow = dictionary.doc2bow(d.split())
        t = lda.get_document_topics(bow)
    

    输出是[(0, 0.88935698141006414), (1, 0.1106430185899358)]

    要回答您的第一个问题,文档的概率确实为 1.0,这就是 get_document_topics 的作用。该文档明确指出它返回给定文档弓的主题分布,作为 (topic_id, topic_probability) 2 元组的列表。

    此外,我尝试为关键字“ierr”获取_term_topics

    t = lda.get_term_topics("ierr", minimum_probability=0.000001),结果是[(1, 0.027292299843400435)],这不过是确定每个主题的单词贡献,这是有道理的。

    因此,您可以根据使用 get_document_topics 获得的主题分布来标记文档,并且可以根据 get_term_topics 给出的贡献确定单词的重要性。

    我希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-02
      • 2014-11-17
      • 1970-01-01
      • 2016-02-29
      相关资源
      最近更新 更多