【问题标题】:Why are LDA predictions incorrect为什么 LDA 预测不正确
【发布时间】:2019-08-07 17:23:21
【问题描述】:

步骤 1

我正在使用 R 和“topicmodels”包从 4.5k 文档语料库构建 LDA 模型。我做了通常的预处理步骤(停用词、削减低/高词频、词形还原)并最终得到一个我很满意的 100 个主题模型。事实上,它几乎是满足我需求的完美模型。

justlda <- LDA(k=100, x=dtm_lemma, method="Gibbs", control=control_list_gibbs)

第二步

然后我使用与上述相同的精确过程对一个新的(模型看不到的)300 个文档语料库进行预处理,然后将其转换为文档术语矩阵,然后使用同一包的“后验”函数进行预测关于新数据的主题。 此语料库来自同一作者,与训练集非常相似。

我的问题

我得到的预测(后验概率)是完全错误的。 这是我用来获取后验的代码:

topics = posterior(justlda, dtm_lemma, control = control_list_gibbs)$topics
  • justlda 是在步骤 1 中使用整个语料库构建的模型。
  • dtm_lemma 是新数据的预处理文档术语矩阵。
  • 控制是 lda 参数(两者相同)。

我觉得不仅预测错误,主题权重也很低。没有什么是主导话题。 (对于这个 100 个主题的模型,大多数主题都是 0.08,我很幸运得到了一个甚至不相关的 0.20 权重......)

我获得了不到一年的 NLP/LDA 和 R 语言经验。我觉得我可能在某个可以解释错误预测的地方犯了一个非常业余的错误?

这样的结果正常吗?我可能做错了什么?

【问题讨论】:

    标签: r nlp lda topic-modeling topicmodels


    【解决方案1】:

    我不是 100% 确定您所说的“错误”是什么意思。我做了一个快速测试,看看posterior 是否适用于新数据。首先,我使用AssociatedPress 数据集的所有文档运行一个模型:

    library(topicmodels)
    data("AssociatedPress")
    ap_lda <- LDA(AssociatedPress, k = 5, control = list(seed = 1234))
    

    根据您的问题,我怀疑您在这里查看每个文档最可能的主题。为了保持可比性,我基于一些整洁的包构建了自己的方法来在这里找到它们:

    library(tidytext)
    library(dplyr)
    library(tidyr)
    ap_documents <- tidy(ap_lda, matrix = "gamma")
    ap_documents %>% 
      group_by(document) %>% 
      top_n(1, gamma) %>% # keep only most likely topic
      arrange(document)
    # A tibble: 2,246 x 3
    # Groups:   document [2,246]
       document topic gamma
          <int> <int> <dbl>
     1        1     4 0.999
     2        2     2 0.529
     3        3     4 0.999
     4        4     4 0.518
     5        5     4 0.995
     6        6     2 0.971
     7        7     1 0.728
     8        8     2 0.941
     9        9     4 0.477
    10       10     5 0.500
    # ... with 2,236 more rows
    

    现在我再次运行相同的 LDA,但保留前 10 个文档:

    AssociatedPress_train <- AssociatedPress[11:nrow(AssociatedPress), ]
    AssociatedPress_test <- AssociatedPress[1:10, ]
    
    ap_lda <- LDA(AssociatedPress_train, k = 5, control = list(seed = 1234))
    

    我使用posterior 获取每个文档的 gamma 值,并再次保留最有可能的值:

    posterior(object = ap_lda, newdata = AssociatedPress_test)$topics %>%
      as_tibble() %>% 
      mutate(document = seq_len(nrow(.))) %>% 
      gather(topic, gamma, -document) %>% 
      group_by(document) %>% 
      top_n(1, gamma) %>% # keep only most probable topic
      arrange(document)
    # A tibble: 10 x 3
    # Groups:   document [10]
       document topic gamma
          <int> <chr> <dbl>
     1        1 4     0.898
     2        2 2     0.497
     3        3 4     0.896
     4        4 4     0.468
     5        5 4     0.870
     6        6 2     0.754
     7        7 1     0.509
     8        8 2     0.913
     9        9 4     0.476
    10       10 2     0.399
    

    除了文档 10 之外的所有文档都具有与以前相同的最可能主题。所以一切似乎都很好!所以我看不出你的代码有什么直接的问题。

    我没有测试过的一件事是,如果训练集和测试集的 DTM 具有不同的列,会发生什么情况。我怀疑这会是个问题。

    这里有一个简单的例子来说明你如何处理这个问题:

    text1 <- tibble(doc = 1, word = LETTERS[1:10])
    text2 <- tibble(doc = 1, word = LETTERS[2:11])
    dtm1 <- text1 %>%
      count(doc, word) %>%
      arrange(word) %>%
      cast_dtm(doc, word, n)
    
    dtm2 <- text2 %>%
      count(doc, word) %>%
      arrange(word) %>%
      cast_dtm(doc, word, n)
    
    all.equal(dtm1$dimnames$Terms, dtm2$dimnames$Terms)
    [1] "10 string mismatches"
    

    我制作了两个 DTM,其中第二个有一个额外的术语,而另一个缺少一个术语。因此,dimnames 是不同的。我们可以通过将 DTM 恢复为整洁的格式来使它们相等,删除多余的术语并在再次转换 DTM 之前添加缺失的术语:

    dtm2_clean <- tidy(dtm2) %>% 
      filter(term %in% dtm1$dimnames$Terms) %>% 
      rbind(tibble(document = 1, 
                   term = dtm1$dimnames$Terms, # adding term but no counts
                   count = 0)) %>% 
      arrange(term) %>% 
      cast_dtm(document, term, count)
    
    all.equal(dtm1$dimnames$Terms, dtm2_clean$dimnames$Terms)
    [1] TRUE
    

    您现在可以将其用作后验的新数据。

    【讨论】:

    • 感谢您的回答。您正在确认我正在以正确的方式进行。从你的最后一行开始,我开始觉得预处理代码可能是错误的。我已经在问题中添加了所有内容。
    • 我认为目标与您最初的问题发生了很大变化。你是新来的,所以你可能不明白这被认为是不好的风格。我已经投入工作,不想完全重新考虑你的问题(我也没有时间)。我为我认为最有可能遇到的问题添加了一些代码(训练和测试 DTM 中的不同术语)。另外,请注意,我在投射 DTM 之前对术语进行了排列,因此它们都按字母顺序排列。
    • 创建不相等的 DTM 似乎可以解释我的问题。我接受了你的回答。很抱歉移动了问题的门柱,我会牢记这一点。他们应该添加一个按钮来向助手发送一瓶酒。你活该!
    • 哈哈不用担心。很高兴我能帮上忙!
    猜你喜欢
    • 1970-01-01
    • 2012-11-21
    • 2018-05-26
    • 2020-06-26
    • 2021-12-27
    • 1970-01-01
    • 2020-03-30
    • 1970-01-01
    • 2017-03-05
    相关资源
    最近更新 更多