Сделайте udpipe_annotate () быстрее - PullRequest
0 голосов
/ 27 ноября 2018

В настоящее время я работаю над документом Text Mining, где хочу абстрагировать релевантные ключевые слова из моего текста (обратите внимание, что у меня есть много, много текстовых документов).

Я использую пакет udpipe.Отличная виньетка в сети (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)

Большое спасибо заранее!

Ответы [ 2 ]

0 голосов
/ 28 ноября 2018

Я добавляю ответ на основе будущего API.Это работает независимо от того, какую ОС (Windows, Mac или Linux) вы используете.

Пакет future.apply имеет все параллельные альтернативы для базового семейства apply.Остальная часть кода основана на ответе @jwijffels.Разница лишь в том, что я использую data.table в функции annotate_splits.

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)
0 голосов
/ 28 ноября 2018

Udpipe пакета R использует библиотеку UDPipe версии 1.2 C ++.Скорость аннотации подробно описана в документе (см. Таблицу Таблица 8 в https://doi.org/10.18653/v1/K17-3009).. Если вы хотите ускорить ее, запустите ее параллельно, так как аннотации тривиально распараллеливаются.

Пример ниже распараллеливается для 16 ядер с использованиемparallel :: mclapply дает вам 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, как я показал выше.

...