如何解释 LDA 组件(使用 sklearn)?

Posted

技术标签:

【中文标题】如何解释 LDA 组件(使用 sklearn)?【英文标题】:How to interpret LDA components (using sklearn)? 【发布时间】:2016-05-10 11:16:45 【问题描述】:

我使用 Latent Dirichlet Allocationsklearn 实现)分析了大约 500 篇科学文章摘要,我得到了包含最重要单词的主题(德语)。我的问题是解释这些与最重要的词相关的值。我假设每个主题的所有单词的概率加起来为 1,但事实并非如此。

如何解释这些值?例如,我希望能够说明为什么主题 #20 的单词比其他主题具有更高的价值。它们的绝对高度与贝叶斯概率有关吗?主题在语料库中更常见吗?我还不能将这些值与 LDA 背后的数学结合起来。

from sklearn.feature_extraction.text import CountVectorizer
from sklearn.decomposition import LatentDirichletAllocation

tf_vectorizer = CountVectorizer(max_df=0.95, min_df=1, top_words=stop_ger,
                                analyzer='word',
                                tokenizer = stemmer_sklearn.stem_ger())

tf = tf_vectorizer.fit_transform(texts)

n_topics = 10
lda = LatentDirichletAllocation(n_topics=n_topics, max_iter=5, 
                                learning_method='online',                 
                                learning_offset=50., random_state=0)

lda.fit(tf)

def print_top_words(model, feature_names, n_top_words):
    for topic_id, topic in enumerate(model.components_):
        print('\nTopic Nr.%d:' % int(topic_id + 1)) 
        print(''.join([feature_names[i] + ' ' + str(round(topic[i], 2))
              +' | ' for i in topic.argsort()[:-n_top_words - 1:-1]]))

n_top_words = 4
tf_feature_names = tf_vectorizer.get_feature_names()
print_top_words(lda, tf_feature_names, n_top_words)

Topic Nr.1: demenzforsch 1.31 | fotus 1.21 | umwelteinfluss 1.16 | forschungsergebnis 1.04 |
Topic Nr.2: fur 1.47 | zwisch 0.94 | uber 0.81 | kontext 0.8 |
...
Topic Nr.20: werd 405.12 | fur 399.62 | sozial 212.31 | beitrag 177.95 | 

【问题讨论】:

您对此有什么结论吗?我面临同样的问题。您是否尝试过评分方法?在我的代码中,它返回一个 NaN... 刚刚在scikit-learn github上找到this isssue,这个实现好像还是有太多bug没用。改用gensim 可能会更好。 感谢分享 gihub 链接! 我在“潜在狄利克雷分配”Blei/Ng/Jordan (p.1007) 中发现了与 sklearns components_ 相关的 lambda 公式。也没有规范化,所以我认为 sklearn 的实现是正确的。就我而言,为一个主题获得非常高的价值非常有趣。这也很符合该主题的那些标记的共同含义。我认为值高度的差异与狄利克雷分布有关,因此更高的值意味着主题在语料库中出现的频率更高。如果我是对的,我们实际上会通过规范化丢失信息。 您可能会丢失“本地”信息,这意味着对您的数据集有一定的偏见。不过,这对于泛化来说并不是一件坏事。 【参考方案1】:

来自文档

组件_ 主题词分布的变分参数。自从完成 主题词分布的条件是 Dirichlet, components_[i, j] 可以看作是表示次数的伪计数 单词 j 被分配给主题 i。也可以看成是分布 标准化后每个主题的单词:model.components_ / model.components_.sum(axis=1)[:, np.newaxis]

因此,如果您对组件进行归一化以评估主题中每个术语的重要性,则这些值可以被视为一个分布。 AFAIU 您不能使用伪计数来比较语料库中两个主题的重要性,因为它们是应用于术语主题分布的平滑因子。

【讨论】:

以上是关于如何解释 LDA 组件(使用 sklearn)?的主要内容,如果未能解决你的问题,请参考以下文章

sklearn - 如何从传递给 GridSearchCV 的管道中检索 PCA 组件和解释方差

ImportError:没有名为“sklearn.lda”的模块

python 使用GenSim的LDA和sklearn的示例

您可以使用 LDA(线性判别分析)作为 sklearn 管道的一部分进行预处理吗?

sklearn 中的因子分析:解释方差

LAD线性判别模型简介及sklearn参数