2016-07-12 2 views
-1

У меня есть (1) набор предложений, (2) набор ключевых слов и (3) баллы (действительные числа) для каждого ключевого слова. Мне нужно назначить оценки предложениям, где оценка предложения = sum_over_keywords (ключевое слово подсчитывается в пределах предложения * оценка ключевого слова).R: как оптимизировать несколько шаблонов для нескольких строк?

Возпроизводимо пример:

library(stringi) 
# generate 200 synthetic sentences containing 15 5-character words each 
set.seed(7122016) 
sentences_splitted = lapply(1:200, function(x) stri_rand_strings(15, 5)) 

# randomly select some words from the sentences as our keywords 
set.seed(7122016) 
keywords = unlist(lapply(sentences_splitted, function(x) if(sample(c(TRUE,FALSE),size=1,prob=c(0.2,0.8))) x[1])) 
len_keywords = length(keywords) 

# assign scores to keywords 
set.seed(7122016) 
my_scores = round(runif(len_keywords),4) 

Теперь озвучивания предложения:

res = system.time(replicate(100, 
    unlist(lapply(sentences_splitted, function (x) 
     sum(unlist(lapply(1:len_keywords, function(y) 
      length(grep(paste0("\\<",keywords[y],"\\>"),x))*my_scores[y] 
     ))))))) 

Я пытался оптимизировать код так, как я мог, но он по-прежнему очень медленно:

user system elapsed 
    11.81 0.01 11.89 

Мне нужно повторить эту операцию больше, чем 200 000 раз ... Есть ли что-то быстрее, чем length(grep(paste0("\\<",keywords[y],"\\>"),x))? Должен ли я использовать что-то еще, кроме вложенных lapply?

ПРИМЕЧАНИЯ:

  • Я уже планирую использовать четыре ядра моего ноутбука параллельно, так , что мне действительно нужно сделать быстрее показано выше основной кусок.
  • Я рад называть код C/C++/Fortran из R, если кто-то предлагает сценарий (к сожалению, я не знаю этих языков).
+0

Какой результат вы получите от 'res'? Я получаю все нули из вашего примера с размерами 200 x 100. Можете ли вы проверить вывод примера? –

+0

@PierreLafortune Я начал новую сессию R и дважды проверил. Я все равно получаю тот же результат: например, «6.23 0.00 6.32» – Antoine

+2

Прошу прощения. Я должен указать. Я понимаю, что время появляется, когда вы окружаете функцию 'replicate' с системным временем. Но удалите оболочку 'system.time', и вы увидите, что фактическая функция не работает. Он производит все нули. –

ответ

3

Мы можем назвать вектор my_scores с ключевыми словами. Помните, что R позволяет подмножество по именам. Поэтому, если мы сможем получить согласованные слова, мы также можем получить оценки:

names(my_scores) <- keywords 
res <- sapply(sentences_splitted, function(x) sum(my_scores[x[x %in% keywords]])) 

Это все, что необходимо. Мы можем протестировать его с помощью меньшего тестируемого примера:

#Create sentences 
sentences_splitted <- list(c("abc", "def", "ghi", "abc"), c("xyz", "abc", "mno", "xyz")) 
keywords <- c("abc", "xyz") 
my_scores <- c(10,20) 

#We should expect 
10 * 2 #first sentence 
10 * 1 and 20 * 2 #second sentence 
#Expected result 
[1] 20 50 

#Check that function works as expected 
names(my_scores) <- keywords 
sapply(sentences_splitted, function(x) sum(my_scores[x[x %in% keywords]])) 
[1] 20 50 
+0

спасибо, но мой вопрос об эффективности. Моя функция работает как ожидалось (см. Изменение, которое я сделал для моего вопроса). – Antoine

+5

Я сдаюсь. Что случилось с этим сайтом? –

+0

@Antoine Это, вероятно, одно из самых эффективных решений, использующих базу R. Far в секунду для более чем 100 повторов. – Jimbou

Смежные вопросы