Quanteda: самый быстрый способ заменить токены леммой из словаря?

Есть ли более быстрая альтернатива R quanteda :: tokens_lookup ()?

Я использую tokens () в пакете quanteda R для токенизации фрейма данных с 2000 документами. В каждом документе от 50 до 600 слов. На моем ПК это занимает пару секунд (Microsoft R Open 3.4.1, Intel MKL (с использованием 2 ядер)).

У меня есть объект словаря, сделанный из фрейма данных из почти 600 000 слов (TERMS) и соответствующей им леммы (PARENT). Есть 80 000 различных лемм.

Я использую tokens_lookup () для замены элементов в списке токенов на их леммы, найденные в словаре. Но на это уходит минимум 1,5 часа. Эта функция слишком медленная для моей проблемы. Есть ли более быстрый способ получить список токенов?

Я хочу напрямую преобразовать список токенов, чтобы сделать ngrams ПОСЛЕ использования словаря. Если бы мне были нужны только онограммы, я мог бы легко сделать это, объединив матрицу функций документа со словарем.

Как мне сделать это быстрее? Преобразовать список токенов в фрейм данных, присоединиться к словарю, преобразовать обратно в упорядоченный список токенов?

Вот пример кода:

library(quanteda)
myText <- c("the man runs home", "our men ran to work")
myDF <- data.frame(myText)
myDF$myText <- as.character(myDF$myText)

tokens <- tokens(myDF$myText, what = "word",
                 remove_numbers = TRUE, remove_punct = TRUE,
                 remove_symbols = TRUE, remove_hyphens = TRUE)
tokens
# tokens from 2 documents.
# text1 :
#   [1] "the"  "man"  "runs" "home"
# 
# text2 :
#   [1] "our"  "men"  "ran"  "to"   "work"

term <- c("man", "men", "woman", "women", "run", "runs", "ran")
lemma <- c("human", "human", "human", "humen", "run", "run", "run")
dict_df <- data.frame(TERM=term, LEMMA=lemma)
dict_df
# TERM LEMMA
# 1   man human
# 2   men human
# 3 woman human
# 4 women humen
# 5   run   run
# 6  runs   run
# 7   ran   run

dict_list <- list( "human" = c("man", "men", "woman", "women") , "run" = c("run", "runs", "ran"))
dict <- quanteda::dictionary(dict_list)
dict
# Dictionary object with 2 key entries.
# - human:
#   - man, men, woman, women
# - run:
#   - run, runs, ran

tokens_lemma <- tokens_lookup(tokens, dictionary=dict, exclusive = FALSE, capkeys = FALSE) 
tokens_lemma
#tokens from 2 documents.
# text1 :
#   [1] "the"   "human" "run"   "home" 
# 
# text2 :
#   [1] "our"   "human" "run"   "to"    "work"

tokens_ngrams <- tokens_ngrams(tokens_lemma, n = 1:2)
tokens_ngrams
#tokens from 2 documents.
# text1 :
#   [1] "the"       "human"     "run"       "home"      "the_human" "human_run" "run_home" 
# 
# text2 :
#   [1] "our"       "human"     "run"       "to"        "work"      "our_human" "human_run" "run_to"    "to_work" 

person Geir Inge    schedule 13.10.2017    source источник
comment
Для токенизации вы также можете взглянуть на пакет tokenizers, который не имеет функций, которые предоставляет пакет quanteta. предлагает но тихо быстро. Я говорю это потому, что провел микробенчмарк для quanteta :: tokens (), tokenizers :: tokenize_words () и моего textTinyR: : tokenize_transform_vec_docs (). Другой вариант - использовать библиотеку (sos); findFn (text), чтобы узнать, есть ли в настоящее время какие-либо другие библиотеки обработки текста, доступные в R.   -  person lampros    schedule 13.10.2017


Ответы (3)


У меня нет списка лемм для тестирования себя, но это самый быстрый способ скрыть типы токенов. Пожалуйста, дайте мне знать, сколько времени это займет (должно быть сделано за несколько секунд).

tokens_convert <- function(x, from, to) {
    type <- attr(x, 'types')
    type_new <- to[match(type, from)]
    type_new <- ifelse(is.na(type_new), type, type_new)
    attr(x, 'types') <- type_new
    quanteda:::tokens_recompile(x)
}

tokens_convert(tokens, dict_df$TERM, dict_df$LEMMA)
person Kohei Watanabe    schedule 14.10.2017
comment
Большое спасибо, @kohei! Функция tokens_convert запускалась за 0,13 секунды (на моем ПК) в списке, созданном tokens () для моих 2000 документов, с использованием таблицы словаря из 600 000 записей. Необходимо, чтобы таблица Dictionary создавалась с stringsAsFactors = FALSE. В функции я использовал tokens_recompile (x, method = C ++). - person Geir Inge; 16.10.2017
comment
Мы добавили в quANTa функцию, аналогичную tokens_replace(). На данный момент это только версия для Github, но, пожалуйста, попробуйте. Я думаю, что мы всегда устанавливаем stringsAsFactors = FALSE при работе с текстовыми данными в R. - person Kohei Watanabe; 25.10.2017

Я использую комбинацию quanteda и udpipe для токенизации и лемматизации моего корпуса. Не знаю, насколько это быстро по сравнению с другими методами. См. Пример ниже:

library(udpipe)
library(quanteda)
dl <- udpipe_download_model(language = "dutch")
udmodel_dutch <- udpipe_load_model(file = "dutch-ud-2.0-170801.udpipe")
txt <- c("Ik ging op reis en ik nam mee: mijn laptop, mijn zonnebril en goed humeur.", "Deze zin is een andere test.")
x <- tokens(txt, what = "sentence", remove_numbers = T, remove_punct = T, remove_url = T, remove_symbols = T)
x <- udpipe_annotate(udmodel_dutch, unlist(x))
x <- as.data.frame(x)
x <- document_term_frequencies(x[, c("doc_id", "lemma")])
dtm <- document_term_matrix(x)
person fritsvegters    schedule 22.10.2017

где lemmas - таблица данных из более чем 100k строк, содержащая столбцы $ word и $ lemma. txttokens, содержащие в среднем более 10 тыс. текстов по 1000 слов каждый:

txttokens <- tokens_replace(txttokens,lemmas$word,lemmas$lemma) 

менее 5 секунд исполнения

person André Ourednik    schedule 14.05.2018