Как лемматизировать корпус с определенным словарем в R?»

Я пытаюсь выполнить lemmatization в корпусе, используя функцию lemmatize_strings() в качестве аргумента для tm_map() пакета tm.

Но я хочу использовать свой собственный словарь ("lexico" - первый столбец с полной формой слова в нижнем регистре, а второй столбец имеет соответствующую лемму замены).

Я пытался использовать:

corpus<-tm_map(corpus, lemmatize_strings)

Но не сработало... Когда я использую:

lemmatize_strings(corpus[[1]], dictionary = lexico)

У меня нет никакой проблемы!

Как я могу поместить свой словарь "lexico" в функцию tm_map()?

Извините за этот вопрос, это моя первая попытка заняться анализом текста в возрасте 48 лет.

Чтобы было понятнее, мой корпус состоит из 2000 документов; выдержка из первого документа:

corpus[[1]][[1]]

[9] "..."

[10] "Nos últimos dias da passada legislatura, a maioria de direita aprovou duas leis que significam enormes recuos nos direitos das cidadãs do país. Fizeram tábua rasa do pronunciamento das cidadãs e cidadãos do país em referendo, optando por humilhar e tentar culpabilizar as mulheres que abortam por sua livre escolha. Estas duas leis são a Lei n.º 134/2015 e a Lei n.º 136/2015, de setembro. A primeira prevê o pagamento de taxas moderadoras na interrupção de gravidez quando for realizada, por opção da mulher, nas primeiras 10 semanas de gravidez. A segunda representa a primeira alteração à Lei n.º 16/2007, de 17 de abril, sobre exclusão de ilicitude nos casos de interrupção voluntária da gravidez." 

Затем работал над файлом словаря (lexico) с такой конфигурацией:

lexico[1:10,]
           termo         lema pos.tag
1             aa            a NCMP000
2           aais          aal NCMP000
3            aal          aal NCMS000
4      aaleniano    aaleniano NCMS000
5     aalenianos    aaleniano NCMP000
6     ab-rogação   ab-rogação NCFS000
7    ab-rogações   ab-rogação NCFP000
8   ab-rogamento ab-rogamento NCMS000
9  ab-rogamentos ab-rogamento NCMP000
10   ab-rogáveis   ab-rogável  AQ0CP0

Когда я использую функцию lemmatize_strings(corpus[[1]], dictionary = lexico), она работает правильно и выдает документ корпуса №1, лемматизированный леммами из моего словаря.

Проблема, которая у меня есть, связана с этой функцией:

> corpus<-tm_map(corpus, lemmatize_strings, dictionary = lexico)
Warning messages:
1: In stringi::stri_extract_all_regex(x, numreg) :
  argument is not an atomic vector; coercing
2: In stringi::stri_extract_all_regex(x, numreg) :
  argument is not an atomic vector; coercing
> corpus[[1]][[1]]
[1] ""

Это просто уничтожит все мои документы в корпусе

> corpus
<<VCorpus>>
Metadata:  corpus specific: 0, document level (indexed): 0
Content:  documents: 2000

Заранее спасибо за ответ!


person Humberto Ferreira    schedule 23.03.2019    source источник
comment
Что значит не получилось? Чтобы упростить получение справки, вы можете предоставить минимальный воспроизводимый пример, как описано здесь: stackoverflow.com/help/mcve. В частности, для вашего вопроса было бы полезно иметь небольшой пример corpus, вашу функцию lemmatize_strings и небольшую часть lexico. Наконец, обратите внимание, что lemmatize_strings принимает дополнительный аргумент dictionary, который вы не передаете tm_map.   -  person dipetkov    schedule 23.03.2019
comment
Спасибо за ваши комментарии/помощь. Я уже добавил больше информации в свой первоначальный вопрос.   -  person Humberto Ferreira    schedule 24.03.2019
comment
Еще один вопрос. Вы ищете решение, которое специально использует пакет tm? Или вас устраивает решение, в котором вместо этого используется quanteda?   -  person dipetkov    schedule 24.03.2019
comment
Ошибка, которую вы получаете, связана с тем, что tm не принимает здесь фрейм данных. То, что вы пытаетесь сделать, насколько мне известно, невозможно в tm. Я вижу два варианта: использовать quanteda, у которого есть функция для этой цели. Или написать свою собственную функцию, основанную на stringi (что и делает tm под капотом).   -  person JBGruber    schedule 24.03.2019
comment
Я использовал эту функцию, которая, я думаю, работает - for (i in 1:length(corpus)) {corpus [[i]][[1]]‹-lemmatize_strings(corpus [[i]][[1]], словарь = лексика)}   -  person Humberto Ferreira    schedule 24.03.2019


Ответы (1)


Вы можете, например, использовать для этого пакет quanteda:

library("quanteda")
text <- "This is a test sentence. We can lemmatize it using quanteda."
dict <- data.frame(
  word = c("is", "using"),
  lemma = c("be", "use"),
  stringsAsFactors = FALSE
)

toks <- tokens(text, remove_punct = TRUE)
toks_lemma <- tokens_replace(toks,
                             pattern = dict$word,
                             replacement = dict$lemma,
                             case_insensitive = TRUE, 
                             valuetype = "fixed")
toks_lemma
tokens from 1 document.
text1 :
 [1] "This"      "be"        "a"         "test"      "sentence"  "We"        "can"       "lemmatize"
 [9] "it"        "use"       "quanteda" 

Функция очень быстрая и, несмотря на название, в основном предназначена для лемматизации.

person JBGruber    schedule 23.03.2019