首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于text2vec包的文本预处理与主题建模

基于text2vec包的文本预处理与主题建模
EN

Stack Overflow用户
提问于 2017-10-20 04:54:50
回答 1查看 1.6K关注 0票数 0

我有大量的文件,我想做主题建模使用text2vec和LDA (吉布斯抽样)。

我需要的步骤如下(顺序):

  1. 从textlibrary(stringr) docs$stringr::str_replace_all <- stringr::str_replace_all中删除数字和符号( docs$text,"[^:alpha:]",“") docs$text <- stringr::str_replace_all(docs$text,"\s+",”")
  2. 移除停止词 库(Text2vec)库(Tm)停止词<- c(tm::秒词(“english”),custom_stopwords) prep_fun <- tolower tok_fun <- word_tokenizer tok_fun <- word_tokenizer令牌<- docs$text%>% prep_fun %>% tok_fun it <- itoken(令牌,id= docs$id,progressbar = FALSE) v <- create_vocabulary(it,%>% prune_vocabulary(term_count_min = 10)向量器<- vocab_vectorizer(v)
  3. 用术语替换同义词

我有一个excel文件,其中第一列是主词,同义词列在第二、第三和.列。我想用主词代替所有同义词(第1栏)。每个词可以有不同数量的同义词。下面是使用"tm“包的代码示例(但我对text2vec包中的代码很感兴趣):

代码语言:javascript
复制
replaceSynonyms <- content_transformer(function(x, syn=NULL)
       {Reduce(function(a,b) {
       gsub(paste0("\\b(", paste(b$syns, collapse="|"),")\\b"), b$word,     a, perl = TRUE)}, syn, x)  })

 l <- lapply(as.data.frame(t(Synonyms), stringsAsFactors = FALSE), #
          function(x) { 
            x <- unname(x) 
            list(word = x[1], syns = x[-1])
          })
names(l) <- paste0("list", Synonyms[, 1])
list2env(l, envir = .GlobalEnv)

synonyms <- list()        
for (i in 1:length(names(l))) synonyms[i] = l[i]

MyCorpus <- tm_map(MyCorpus, replaceSynonyms, synonyms)
  1. 转换为文档术语矩阵 dtm <- create_dtm(it,向量器)
  2. LDA模型在文档术语矩阵中的应用 doc_topic_prior <- 0.1 #可以根据数据选择吗?lda_model <- LDA$new(n_topics = 10,doc_topic_prior = doc_topic_prior,topic_word_prior =0.0 1) doc_topic_distr <- lda_model$fit_transform(dtm,n_iter =10,convergence_tol <- 0.0 1,check_convergence_every_n = 10)

步骤3中的MyCorpurs是使用"tm“包获得的语料库。步骤2和步骤3不一起工作,因为步骤2的输出是语音,但是步骤3的输入是"tm“语料库。

我的第一个问题是,如何使用text2vec包(以及兼容的包)完成所有步骤,因为我发现它非常有效;感谢Dmitriy。

第二:如何在第5步中为LDA中的参数设置最优值?是否可以根据数据自动设置它们?

感谢曼努埃尔·比克尔在我的岗位上所做的修正。

谢谢你,山姆

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-10-20 12:51:54

回复您的评论:

第一个问题:同义词替换问题已经在这里得到了回答:Replace words in text2vec efficiently。用分词检查count的答案。模式和替换可以是ngram(多个单词短语)。请注意,Dmitriy Selivanov的第二个答案使用word_tokenizer(),不包括所提供的ngram替换的情况。

在删除停止词之前,有什么理由需要替换同义词吗?通常情况下,这个顺序不应该引起问题;或者您有一个例子,其中切换顺序会产生显著的不同结果吗?如果您真的想在删除停止字之后替换同义词,我想您必须在使用text2vec时将这些更改应用于dtm。如果这样做,您需要允许ngram在您的dtm中与最小的ngram长度包括在您的同义词中。我在下面的代码中提供了一个解决方案,作为一种选择。请注意,在dtm中允许更高的数值会产生噪音,这可能会或不会影响您的下游任务(您可能可以在词汇表步骤中删除大部分噪音)。因此,替换早期的ngram似乎是一个更好的解决方案。

第二个问题:,您可以检查textmineR包的包(和源代码),这可以帮助您选择最佳的主题数量,也可以选择这个问题的答案( Topic models: cross validation with loglikelihood or perplexity )。关于先验的处理,我还没有弄清楚不同的包,如text2vec (WarpLDA算法)、lda (折叠Gibbs抽样算法等)或topicmodels (标准的吉布斯抽样和变分期望最大化算法)是如何处理这些值的。作为一个起点,您可能会看到topicmodels的详细文档“2.2.估测”一章告诉您如何估计在“2.1Model规范”中定义的alpha和beta参数。

为了学习,请注意,您的代码在两个点产生了错误,我已经对其进行了修改:(1)您需要在create_vocabulary()__中为秒词使用正确的名称,而不是stop_words,因为您将名称定义为这样(2)在lda模型定义中不需要vocabulary =... --也许您使用的是较旧版本的text2vec__?

代码语言:javascript
复制
library(text2vec) 
library(reshape2)
library(stringi)

#function proposed by @count
mgsub <- function(pattern,replacement,x) {
  if (length(pattern) != length(replacement)){
    stop("Pattern not equal to Replacment")
  } 
  for (v in 1:length(pattern)) {
    x  <- gsub(pattern[v],replacement[v],x, perl = TRUE)
  }
  return(x )
}

docs <- c("the coffee is warm",
          "the coffee is cold",
          "the coffee is hot",
          "the coffee is boiling like lava",
          "the coffee is frozen",
          "the coffee is perfect",
          "the coffee is warm almost hot"
)

synonyms <- data.frame(mainword = c("warm", "cold")
                       ,syn1 = c("hot", "frozen")
                       ,syn2 = c("boiling like lava", "")
                       ,stringsAsFactors = FALSE)

synonyms[synonyms == ""] <- NA

synonyms <- reshape2::melt(synonyms
                           ,id.vars = "mainword"
                           ,value.name = "synonym"
                           ,na.rm = TRUE)

synonyms <- synonyms[, c("mainword", "synonym")]


prep_fun <- tolower
tok_fun <- word_tokenizer
tokens <- docs %>% 
  #here is where you might replace synonyms directly in the docs
  #{ mgsub(synonyms[,"synonym"], synonyms[,"mainword"], . ) } %>%
  prep_fun %>% 
  tok_fun
it <- itoken(tokens, 
             progressbar = FALSE)

v <- create_vocabulary(it,
                       sep_ngram = "_",
                       ngram = c(ngram_min = 1L
                                 #allow for ngrams in dtm
                                 ,ngram_max = max(stri_count_fixed(unlist(synonyms), " "))
                                 )
)

vectorizer <- vocab_vectorizer(v)
dtm <- create_dtm(it, vectorizer)

#ngrams in dtm
colnames(dtm)

#ensure that ngrams in synonym replacement table have the same format as ngrams in dtm
synonyms <- apply(synonyms, 2, function(x) gsub(" ", "_", x))

colnames(dtm) <- mgsub(synonyms[,"synonym"], synonyms[,"mainword"], colnames(dtm))


#only zeros/ones in dtm since none of the docs specified in my example
#contains duplicate terms
dim(dtm)
#7 24
max(dtm)
#1

#workaround to aggregate colnames in dtm
#I think there is no function `colsum` that allows grouping
#therefore, a workaround based on rowsum
#not elegant because you have to transpose two times, 
#convert to matrix and reconvert to sparse matrix
dtm <- 
  Matrix::Matrix(
    t(
      rowsum(t(as.matrix(dtm)), group = colnames(dtm))
    )
    , sparse = T)


#synonyms in columns replaced
dim(dtm)
#7 20
max(dtm)
#2
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46842595

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档