使 udpipe_annotate() 更快
Make udpipe_annotate() faster
我目前正在处理一个文本挖掘文档,我想从我的文本中提取相关的关键字(请注意,我有很多很多文本文档)。
我正在使用 udpipe 包。一个很棒的 Vignette 在 (http://bnosac.be/index.php/blog/77-an-overview-of-keyword-extraction-techniques) 上在线。一切正常,但是当我 运行 代码时,
部分
x <- udpipe_annotate(ud_model, x = comments$feedback)
真的非常慢(尤其是当您有很多文本时)。 有没有人知道我如何更快地获得这部分?解决方法当然没问题。
library(udpipe)
library(textrank)
## First step: Take the Spanish udpipe model and annotate the text. Note: this takes about 3 minutes
data(brussels_reviews)
comments <- subset(brussels_reviews, language %in% "es")
ud_model <- udpipe_download_model(language = "spanish")
ud_model <- udpipe_load_model(ud_model$file_model)
x <- udpipe_annotate(ud_model, x = comments$feedback) # This part is really, really slow
x <- as.data.frame(x)
非常感谢!
R 包 udpipe 使用 UDPipe 版本 1.2 C++ 库。论文中详细说明了注释速度(参见table Table 8 in https://doi.org/10.18653/v1/K17-3009)。如果你想加快它的速度,运行 它是并行的,因为注释是可以并行处理的。
下面的示例使用 parallel::mclapply 跨 16 个内核并行化,如果您当然有 16 个内核,则大型语料库的速度可以提高 16 倍。您可以使用您拥有的任何并行化框架,下面我使用了并行包 - 如果您在 Windows 上,则需要例如parallel::parLapply 但没有什么能阻止您使用其他并行选项(snow / multicore / future / foreach /...)来并行注释。
library(udpipe)
library(data.table)
library(parallel)
data(brussels_reviews)
comments <- subset(brussels_reviews, language %in% "fr")
ud_model <- udpipe_download_model(language = "french-partut")
annotate_splits <- function(x, file) {
model <- udpipe_load_model(file)
x <- udpipe_annotate(model, x = x$feedback, doc_id = x$id, tagger = "default", parser = "default")
as.data.frame(x, detailed = TRUE)
}
corpus_splitted <- split(comments, seq(1, nrow(comments), by = 100))
annotation <- mclapply(corpus_splitted, FUN = function(x, file){
annotate_splits(x, file)
}, file = ud_model$file_model, mc.cores = 16)
annotation <- rbindlist(annotation)
请注意,udpipe_load_model 也需要一些时间,因此可能更好的策略是在您机器上的内核数量上并行化它,而不是像我上面显示的那样以 100 个为一组。
我正在添加一个基于未来的答案 API。这与您使用的OS(Windows、mac 或linux 风格无关。
future.apply 包具有基本 *apply 系列的所有并行替代方案。其余代码基于@jwijffels 的回答。唯一的区别是我在 annotate_splits 函数中使用了 data.table。
library(udpipe)
library(data.table)
data(brussels_reviews)
comments <- subset(brussels_reviews, language %in% "es")
ud_model <- udpipe_download_model(language = "spanish", overwrite = F)
ud_es <- udpipe_load_model(ud_model)
# returns a data.table
annotate_splits <- function(x, file) {
ud_model <- udpipe_load_model(file)
x <- as.data.table(udpipe_annotate(ud_model,
x = x$feedback,
doc_id = x$id))
return(x)
}
# load parallel library future.apply
library(future.apply)
# Define cores to be used
ncores <- 3L
plan(multiprocess, workers = ncores)
# split comments based on available cores
corpus_splitted <- split(comments, seq(1, nrow(comments), by = 100))
annotation <- future_lapply(corpus_splitted, annotate_splits, file = ud_model$file_model)
annotation <- rbindlist(annotation)
您也可以使用 furrr
和 future
库来完成此操作,它们具有进度条的额外好处。
我在其他两个答案中感到困惑的一件事是他们在其功能中实现了 udpipe_load_model
。您可以先在函数外部加载一次模型,这样函数就不必在每次运行时都加载模型。
library(udpipe)
library(future)
library(furrr)
data(brussels_reviews)
comments <- subset(brussels_reviews, language %in% "es")
downloaded_model <- udpipe_download_model(language = "spanish", overwrite = FALSE)
model <- udpipe_load_model(downloaded_model)
annotate_splits <- function(text) {
anno <- udpipe_annotate(model, x = text$feedback, doc_id = text$id, tagger = "default", parser = "default")
x <- as.data.frame(anno, detailed = TRUE)
return(x)
}
split_corpus <- split(comments, seq(1, nrow(comments), by = 100))
#recommend setting workers equal to number of your computer's cores
plan(multisession, workers = 2)
dfs <- future_map(split_corpus, annotate_splits, .progress = TRUE)
annotated_df <- dplyr::bind_rows(dfs)
我目前正在处理一个文本挖掘文档,我想从我的文本中提取相关的关键字(请注意,我有很多很多文本文档)。
我正在使用 udpipe 包。一个很棒的 Vignette 在 (http://bnosac.be/index.php/blog/77-an-overview-of-keyword-extraction-techniques) 上在线。一切正常,但是当我 运行 代码时,
部分x <- udpipe_annotate(ud_model, x = comments$feedback)
真的非常慢(尤其是当您有很多文本时)。 有没有人知道我如何更快地获得这部分?解决方法当然没问题。
library(udpipe)
library(textrank)
## First step: Take the Spanish udpipe model and annotate the text. Note: this takes about 3 minutes
data(brussels_reviews)
comments <- subset(brussels_reviews, language %in% "es")
ud_model <- udpipe_download_model(language = "spanish")
ud_model <- udpipe_load_model(ud_model$file_model)
x <- udpipe_annotate(ud_model, x = comments$feedback) # This part is really, really slow
x <- as.data.frame(x)
非常感谢!
R 包 udpipe 使用 UDPipe 版本 1.2 C++ 库。论文中详细说明了注释速度(参见table Table 8 in https://doi.org/10.18653/v1/K17-3009)。如果你想加快它的速度,运行 它是并行的,因为注释是可以并行处理的。
下面的示例使用 parallel::mclapply 跨 16 个内核并行化,如果您当然有 16 个内核,则大型语料库的速度可以提高 16 倍。您可以使用您拥有的任何并行化框架,下面我使用了并行包 - 如果您在 Windows 上,则需要例如parallel::parLapply 但没有什么能阻止您使用其他并行选项(snow / multicore / future / foreach /...)来并行注释。
library(udpipe)
library(data.table)
library(parallel)
data(brussels_reviews)
comments <- subset(brussels_reviews, language %in% "fr")
ud_model <- udpipe_download_model(language = "french-partut")
annotate_splits <- function(x, file) {
model <- udpipe_load_model(file)
x <- udpipe_annotate(model, x = x$feedback, doc_id = x$id, tagger = "default", parser = "default")
as.data.frame(x, detailed = TRUE)
}
corpus_splitted <- split(comments, seq(1, nrow(comments), by = 100))
annotation <- mclapply(corpus_splitted, FUN = function(x, file){
annotate_splits(x, file)
}, file = ud_model$file_model, mc.cores = 16)
annotation <- rbindlist(annotation)
请注意,udpipe_load_model 也需要一些时间,因此可能更好的策略是在您机器上的内核数量上并行化它,而不是像我上面显示的那样以 100 个为一组。
我正在添加一个基于未来的答案 API。这与您使用的OS(Windows、mac 或linux 风格无关。
future.apply 包具有基本 *apply 系列的所有并行替代方案。其余代码基于@jwijffels 的回答。唯一的区别是我在 annotate_splits 函数中使用了 data.table。
library(udpipe)
library(data.table)
data(brussels_reviews)
comments <- subset(brussels_reviews, language %in% "es")
ud_model <- udpipe_download_model(language = "spanish", overwrite = F)
ud_es <- udpipe_load_model(ud_model)
# returns a data.table
annotate_splits <- function(x, file) {
ud_model <- udpipe_load_model(file)
x <- as.data.table(udpipe_annotate(ud_model,
x = x$feedback,
doc_id = x$id))
return(x)
}
# load parallel library future.apply
library(future.apply)
# Define cores to be used
ncores <- 3L
plan(multiprocess, workers = ncores)
# split comments based on available cores
corpus_splitted <- split(comments, seq(1, nrow(comments), by = 100))
annotation <- future_lapply(corpus_splitted, annotate_splits, file = ud_model$file_model)
annotation <- rbindlist(annotation)
您也可以使用 furrr
和 future
库来完成此操作,它们具有进度条的额外好处。
我在其他两个答案中感到困惑的一件事是他们在其功能中实现了 udpipe_load_model
。您可以先在函数外部加载一次模型,这样函数就不必在每次运行时都加载模型。
library(udpipe)
library(future)
library(furrr)
data(brussels_reviews)
comments <- subset(brussels_reviews, language %in% "es")
downloaded_model <- udpipe_download_model(language = "spanish", overwrite = FALSE)
model <- udpipe_load_model(downloaded_model)
annotate_splits <- function(text) {
anno <- udpipe_annotate(model, x = text$feedback, doc_id = text$id, tagger = "default", parser = "default")
x <- as.data.frame(anno, detailed = TRUE)
return(x)
}
split_corpus <- split(comments, seq(1, nrow(comments), by = 100))
#recommend setting workers equal to number of your computer's cores
plan(multisession, workers = 2)
dfs <- future_map(split_corpus, annotate_splits, .progress = TRUE)
annotated_df <- dplyr::bind_rows(dfs)