主题建模时为每个文本分配多个主题

问题描述

使用下面的 quanteda 函数,我想为每个文本分配多个主题,但不确定如何实现这一点。目前它只为每个文本分配一个主题

corp_news <- data_corpus_inaugural

news_dfm <- dfm(corp_news,remove_punct = TRUE,remove_numbers = TRUE,remove_symbol = TRUE,remove=stopwords("en"))

tmod_lda <- textmodel_lda(news_dfm,k = 10)

news_dfm$topic <- topics(tmod_lda)

解决方法

这在您使用的 seededlda 包中没有实现,我认为任何其他 LDA 包也没有做到这一点。但是,topics 只是选择具有最高 theta 值的主题。这直接来自source code

#' @export
#' @method topics textmodel_lda
topics.textmodel_lda <- function(x) {
    result <- factor(max.col(x$theta),labels = colnames(x$theta),levels = seq_len(ncol(x$theta)))
    result[rowSums(x$data) == 0] <- NA
    return(result)
}

我们可以修改这个函数来返回任意数量的主题,从最可能到最不可能排序:

topicsn <- function(x,n = 1) {
  if (n == 1) {
    result <- factor(max.col(x$theta),levels = seq_len(ncol(x$theta)))
  } else if (n > 1) {
    result <- factor(apply(x$theta,1,order)[,seq_len(n)],levels = seq_len(ncol(x$theta)))
    result <- matrix(result,ncol = n)
    colnames(result) <- paste0("top_topic_",seq_len(n))
  }
  
  return(result)
}

现在我再次运行您的代码(由于新 quanteda 中的语法有所不同,因此略有更改:

library(quanteda)
library(seededlda)
corp_news <- data_corpus_inaugural

news_dfm <- corp_news %>% 
  tokens(remove_numbers = TRUE,remove_symbol = TRUE) %>% 
  tokens_remove(stopwords("en")) %>% 
  dfm()

tmod_lda <- textmodel_lda(news_dfm,k = 10)

现在我们可以使用该函数返回两个热门话题:

topicsn(tmod_lda,2)
#>       top_topic_1 top_topic_2
#>  [1,] "topic3"    "topic1"   
#>  [2,] "topic10"   "topic2"   
#>  [3,] "topic4"    "topic4"   
#>  [4,] "topic1"    "topic5"   
#>  [5,] "topic5"    "topic9"   
#>  [6,] "topic9"    "topic10"  
#>  [7,] "topic8"    "topic3"   
#>  [8,] "topic2"    "topic8"   
#>  [9,] "topic6"    "topic6"   
#> [10,] "topic7"    "topic7"

对于第一个文本,最流行的主题是“topic3”,然后是“topic1”,依此类推。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...