R 在主题建模中寻找每个句子中的主导主题

R 在主题建模中寻找每个句子中的主导主题,r,nlp,text-mining,topic-modeling,R,Nlp,Text Mining,Topic Modeling,我在R中找不到答案的一个问题是,如何在NLP模型中找到每个句子的主要主题? 假设我有这样的数据帧: comment <- c("outstanding renovation all improvements are topoftheline and done with energy efficiency in mind low monthly utilities even the interior", "solidly constru

我在R中找不到答案的一个问题是,如何在NLP模型中找到每个句子的主要主题? 假设我有这样的数据帧:

comment <- c("outstanding renovation all improvements are topoftheline and done with energy efficiency in mind low monthly utilities even the interior",
             "solidly constructed lovingly maintained sf crest built",
             "one year since built new this well designed storey home",
             "beautiful street large bdm in the heart of lynn valley over sqft bathrooms",
             "rare to find legal beautiful upgr in port moody centre with a mountain view all bedroom units were nicely renovated",
             "fantastic opportunity to get value for the money excellent family home in desirable blueridge with legal selfcontained bachelor suite on the main floor great location close to swimming ice skating community",
             "original owner tired but rock solid perfect location half a block to norquay elementary school and short quiet blocks to slocan park and sky train station")

id <- c(1,2,3,4,5,6,7)

data <- data.frame(id, comment)
现在根据我得到的结果,我想在主题建模中找到每个句子中最主要的主题。例如,我想知道,对于评论1(“出色的翻新,所有改进都是在考虑能源效率的情况下进行的,每月公用设施甚至室内设施都很低”),哪一个主题(主题1或主题2)是最主要的


有人能帮我回答这个问题吗?我们有任何软件包可以做到这一点吗?

使用quantedatopicmodels非常容易。前者用于文本数据的数据管理和定量分析,后者用于主题建模推理

在这里,我将您的
注释
对象转换为
语料库
,然后转换为
dfm
。然后,我将其转换为可通过topicmodels理解

函数
LDA()。特别是,使用
get_topics()
可以获得每个文档最可能的主题。如果您想查看文档主题权重,可以使用
ldamodel@gamma
。您将看到
get_topics()
完全按照您的要求执行

请看看这对你是否有效

库(quanteda)
#>软件包版本:2.1.2
#>并行计算:使用16个线程中的2个。
#>看https://quanteda.io 有关教程和示例。
#> 
#>附加程序包:“quanteda”
#>以下对象已从“package:utils”屏蔽:
#> 
#>看法
库(topicmodels)
评论[5,]0.5037667 0.4962333
#> [6,] 0.5000727 0.4999273
#> [7,] 0.5176960 0.4823040

由(v1.0.0)创建于2021-03-18,我同意另一个答案,即
quanteda
topicmodels
是更好的选择。也许还可以从
quanteda
作者之一那里了解哪一个是LDA实现(具有您不必使用的额外功能)

但是,如果您想坚持选择
tidytext
textmineR
,您可以这样做

首先,我简化了您的预处理,因为您执行了一些我认为不必要的步骤:

库(tidyverse)
图书馆(tidytext)
文本\u清理\u标记%
unnest_标记(单词、注释)%%>%
变异(单词=str_删除(单词,[[:digit:][].[:punct:][]))%>%
过滤器(!(nchar(字)%
反加入(停止单词,by=“word”)%>%
变异(单词=雪球C::词干(单词))
然后根据
textmineR
示例运行LDA:

lda%
cast_稀疏(id,word)%>%
textmineR::FitLdaModel(k=2,
迭代次数=200次,
伯宁=175,
优化α=真,
计算可能性=真,
计算(r2=真)
现在,LDA的所有实现都提供了两个重要结果:

  • phi
    (φ),显示语料库中每个单词在每个主题上的得分。phi值越高,该单词在该特定主题中越普遍
  • theta
    (θ),显示语料库中每个文档在每个主题上的得分。theta值越高,主题在文档中越普遍。(
    topicmodels
    出于某种原因称之为gamma。)
换言之,要在文本中找到最主要的主题,你所要做的就是:

lda$theta%>%
as_tible()%>%
行()
mutate(top=which.max(c_overs(everything()))%>%#查找每行dplyr样式的最高值
绑定列(数据,.%>%#绑定到原始数据
作为可存储的()#只是为了更好地打印
#>#tibble:7 x 5
#>id注释t_1 t_2顶部
#>                                                        
#>1.杰出的翻新所有改进均为t…0.892 0.108 1
#>2坚固的结构,精心维护的sf盾徽…0.0161 0.984 2
#>3新开的这家设计精良的商店一年后……0.0238 0.976 2
#>4美丽街道林恩中心的大型bdm v…0.986 0.0139 1
#>5穆迪港罕见的合法美丽upgr…0.992 0.00820 1
#>6获得物有所值的绝佳机会…0.266 0.734 2
#>7原车主疲惫但坚如磐石的完美locat…0.00549 0.995 2
由(v1.0.0)于2021年3月18日创建


我还建议你阅读Julia Silge关于这件事的文章。例如,和。

我感谢你的帮助,你解释这件事的方式让我更容易。现在我对这些参数的含义有了更好的理解,因为某种原因,
bind_cols(data,.)%%>%%
这段代码给了我一个错误:错误:输入必须是一个向量,而不是一个函数。非常感谢。这正是我想要的。我只有一个问题。我想知道我应该在哪里进行清理。如果你看一下我的代码,我正在对我的文档进行一系列清理,我应该在制作语料库之前还是之后进行清理帽子?另外,你能解释一下你在哪里使用了
quanteda
软件包吗?你的解决方案看起来很干净,很完美,但我不知道为什么我们有
dfm
或者什么
docvars(mycorp,“id”)另外,我的主数据框已经有
id
作为某种文档编号。在您的方法中,我如何使用我在原始数据库中拥有的相同id,而不是分配1到7。我猜您正在使用
docvars(mycorp,“id”)添加id
text_cleaning_tokens <- data %>% 
  tidytext::unnest_tokens(word, comment)
text_cleaning_tokens$word <- gsub('[[:digit:]]+', '', text_cleaning_tokens$word)
text_cleaning_tokens$word <- gsub('[[:punct:]]+', '', text_cleaning_tokens$word)


text_cleaning_tokens <- text_cleaning_tokens %>% filter(!(nchar(word) == 1))%>% 
  anti_join(stop_words)

stemmed_token <- text_cleaning_tokens %>% mutate(word=wordStem(word))


tokens <- stemmed_token %>% filter(!(word==""))
tokens <- tokens %>% mutate(ind = row_number())
tokens <- tokens %>% group_by(id) %>% mutate(ind = row_number()) %>%
  tidyr::spread(key = ind, value = word)
tokens [is.na(tokens)] <- ""
tokens <- tidyr::unite(tokens, clean_remark,-id,sep =" " )
tokens$clean_remark <- trimws(tokens$clean_remark)
             t_1            t_2
1         beauti          built
2          block           home
3          renov          legal
4       bathroom          locat
5            bdm       bachelor
6      bdm_heart  bachelor_suit
7  beauti_street  block_norquai
8    beauti_upgr       blueridg
9        bedroom blueridg_legal
10  bedroom_unit   built_design