首页 文章

潜在的Dirichlet分配与先前的主题词

提问于
浏览
1

Context

我正试图从Scikit-Learn's decomposition module中使用Latent Dirichlet allocation从一组文本中提取主题 . 除了找到/选择的主题词的质量之外,这非常有效 .

Li et al (2017)的一篇文章中,作者描述了使用先前的主题词作为LDA的输入 . 他们手动选择4个主题和与这些主题相关/属于的主要词 . 对于这些单词,他们将默认值设置为关联主题的高数字,将0设置为其他主题 . 所有其他单词(不是为主题手动选择)都为所有主题赋予相同的值(1) . 该值矩阵用作LDA的输入 .

My question

如何使用Scikit-Learn中的LatentDirichletAllocation模块使用自定义默认值矩阵(先前主题词)作为输入创建类似的分析?

(我知道有一个 topic_word_prior 参数,但它只需要一个浮点而不是一个具有不同'default values'的矩阵 . )

EDIT

Solution

使用@Anis的帮助,我创建了原始模块的子类,并编辑了设置起始值矩阵的函数 . 对于您希望作为输入提供的所有先前主题词,它通过将值与该(先前)词的主题值相乘来转换 components_ 矩阵 .

这是代码:

# List with prior topic words as tuples
# (word index, [topic values])
prior_topic_words = []

# Example (word at index 3000 belongs to topic with index 0)
prior_topic_words.append(
    (3000, [(np.finfo(np.float64).max/4),0.,0.,0.,0.])
)

# Custom subclass for PTW-guided LDA
from sklearn.utils import check_random_state
from sklearn.decomposition._online_lda import _dirichlet_expectation_2d
class PTWGuidedLatentDirichletAllocation(LatentDirichletAllocation):

    def __init__(self, n_components=10, doc_topic_prior=None, topic_word_prior=None, learning_method=’batch’, learning_decay=0.7, learning_offset=10.0, max_iter=10, batch_size=128, evaluate_every=-1, total_samples=1000000.0, perp_tol=0.1, mean_change_tol=0.001, max_doc_update_iter=100, n_jobs=None, verbose=0, random_state=None, n_topics=None, ptws=None):
        super(PTWGuidedLatentDirichletAllocation, self).__init__(n_components, doc_topic_prior, topic_word_prior, learning_method, learning_decay, learning_offset, max_iter, batch_size, evaluate_every, total_samples, perp_tol, mean_change_tol, max_doc_update_iter, n_jobs, verbose, random_state, n_topics)
        self.ptws = ptws

    def _init_latent_vars(self, n_features):
        """Initialize latent variables."""

        self.random_state_ = check_random_state(self.random_state)
        self.n_batch_iter_ = 1
        self.n_iter_ = 0

        if self.doc_topic_prior is None:
            self.doc_topic_prior_ = 1. / self.n_topics
        else:
            self.doc_topic_prior_ = self.doc_topic_prior

        if self.topic_word_prior is None:
            self.topic_word_prior_ = 1. / self.n_topics
        else:
            self.topic_word_prior_ = self.topic_word_prior

        init_gamma = 100.
        init_var = 1. / init_gamma
        # In the literature, this is called `lambda`
        self.components_ = self.random_state_.gamma(
            init_gamma, init_var, (self.n_topics, n_features))

        # Transform topic values in matrix for prior topic words
        if self.ptws is not None:
            for ptw in self.ptws:
                word_index = ptw[0]
                word_topic_values = ptw[1]
                self.components_[:, word_index] *= word_topic_values

        # In the literature, this is `exp(E[log(beta)])`
        self.exp_dirichlet_component_ = np.exp(
            _dirichlet_expectation_2d(self.components_))

启动与原始 LatentDirichletAllocation 类相同,但现在您可以使用 ptws 参数提供先前的主题词 .

1 回答

  • 2

    看了一下源代码和文档之后,在我看来最简单的事情就是子类 LatentDirichletAllocation 并且只覆盖 _init_latent_vars 方法 . 在 fit 中调用的方法是创建 components_ 属性,该属性是用于分解的矩阵 . 通过重新实现此方法,您可以按照您想要的方式进行设置,尤其是增加相关主题/功能的先前权重 . 您将在那里重新实现用于初始化的纸张逻辑 .

相关问题