2

我有一个很大的文本正文,我想有效地用它们各自的同义词替换单词(例如用同义词“car”替换所有出现的“automobile”)。但我很难找到一种合适的(有效的方法)来做到这一点。

对于以后的分析,我使用该text2vec库并希望将该库用于此任务(避免tm减少依赖关系)。

一种(低效)方式如下所示:

# setup data
text <- c("my automobile is quite nice", "I like my car")

syns <- list(
  list(term = "happy_emotion", syns = c("nice", "like")),
  list(term = "car", syns = c("automobile"))
)

我的蛮力解决方案是有这样的东西并使用循环来查找单词并替换它们

library(stringr)
# works but is probably not the best...
text_res <- text
for (syn in syns) {
  regex <- paste(syn$syns, collapse = "|")
  text_res <-  str_replace_all(text_res, pattern = regex, replacement = syn$term)
}
# which gives me what I want
text_res
# [1] "my car is quite happy_emotion" "I happy_emotion my car" 

我曾经使用MrFlick 的tm这种方法(使用and )来做到这一点,但我想通过替换更快的.tm::content_transformertm::tm_maptmtext2vec

我想最佳解决方案是以某种方式使用text2vecs itoken,但我不确定如何使用。有任何想法吗?

4

3 回答 3

3

很晚了,但我还是想加我的 2 美分。我看到了 2 个解决方案

  1. 对您的str_replace_all. 由于它是内部矢量化的,因此您可以在没有循环的情况下进行所有替换。我认为它会更快,但我没有做任何基准测试。

    regex_batch = sapply(syns, function(syn) paste(syn$syns, collapse = "|"))  
    names(regex_batch) = sapply(syns, function(x) x$term)  
    str_replace_all(text, regex_batch)  
    
  2. 这个任务自然是用于哈希表查找。据我所知,最快的实现是在fastmatch包中。因此,您可以编写自定义标记器,例如:

    library(fastmatch)
    
    syn_1 = c("nice", "like")
    names(syn_1) = rep('happy_emotion', length(syn_1))
    syn_2 = c("automobile")
    names(syn_2) = rep('car', length(syn_2))
    
    syn_replace_table = c(syn_1, syn_2)
    
    custom_tokenizer = function(text) {
      word_tokenizer(text) %>% lapply(function(x) {
        i = fmatch(x, syn_replace_table)
        ind = !is.na(i)
        i = na.omit(i)
        x[ind] = names(syn_replace_table)[i]
        x
      })
    }
    

我敢打赌,第二种解决方案会更快,但需要做一些基准测试。

于 2017-01-26T06:09:53.650 回答
2

使用基础 R 这应该可以工作:

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)
    }
return(x )
}

mgsub(c("nice","like","automobile"),c(rep("happy_emotion",2),"car"),text)
于 2017-01-11T09:52:18.257 回答
1

Dmitriy Selivanov 解决方案的第一部分需要稍作改动。

library(stringr)    

text <- c("my automobile is quite nice", "I like my car")

syns <- list(
             list(term = "happy_emotion", syns = c("nice", "like")),
             list(term = "car", syns = c("automobile"))
             )

regex_batch <- sapply(syns, function(syn) syn$term)  
names(regex_batch) <- sapply(syns, function(x) paste(x$syns, collapse = "|"))  
text_res <- str_replace_all(text, regex_batch) 

text_res
[1] "my car is quite happy_emotion" "I happy_emotion my car"  
于 2017-10-26T03:40:59.960 回答