Как выполнить лемматизацию в R?

Этот вопрос является возможным дубликатом лемматизатора в R или python (am, are, is -> be?), но я добавляю его снова, так как предыдущий был закрыт, говоря, что он был слишком широким, и единственный ответ, который он имеет, неэффективен (поскольку для этого он обращается к внешнему веб-сайту, что слишком медленно, так как у меня очень большой корпус, для которого нужно найти леммы). Таким образом, часть этого вопроса будет похожа на вышеупомянутый вопрос.

Согласно Википедии, лемматизация определяется как:

Лемматизация (или лемматизация) в лингвистике - это процесс группирования различных флективных форм слова, чтобы их можно было анализировать как единый элемент.

Простой поиск в Google лемматизации в R будет только указывать на пакет wordnet of R. Когда я попробовал этот пакет, ожидая, что ввод символьного вектора c("run", "ran", "running") в функцию лемматизации приведет к c("run", "run", "run"), я увидел, что это Пакет предоставляет только функции, аналогичные функции grepl, через различные имена фильтров и словарь.

Пример кода из пакета wordnet, который дает максимум 5 слов, начинающихся с "car", как объясняет само название фильтра:

filter <- getTermFilter("StartsWithFilter", "car", TRUE)
terms <- getIndexTerms("NOUN", 5, filter)
sapply(terms, getLemma)

Вышеупомянутое НЕ та лемматизация, которую я ищу. Я ищу, используя R, я хочу найти истинные корни слов: (например, от c("run", "ran", "running") до c("run", "run", "run")).


person StrikeR    schedule 29.01.2015    source источник
comment
извините, но я думаю, что это ищет пакет или инструмент - не пытается решить конкретную проблему программирования. Может быть, есть форумы по компьютерной лингвистике / интеллектуальному анализу текста, о которых вы могли бы спросить?   -  person Ben Bolker    schedule 29.01.2015
comment
Я думаю, что этот вопрос немного отличается от типичных вопросов о пакете / поиске инструментов, которые подходят близко. Он спрашивает, как выполнить лемматизацию в R, что является вопросом программирования. @StrikeR: Я предлагаю вам изменить последнюю строку Is there ... чтобы избежать закрытия этого вопроса.   -  person Chthonic Project    schedule 29.01.2015
comment
@ChthonicProject благодарит за предложение. Внес изменения соответственно.   -  person StrikeR    schedule 30.01.2015
comment
Это не вопрос программирования. У программной части есть простой ответ - найти / создать словарь и выполнить поиск.   -  person eddi    schedule 03.02.2015
comment
@eddi Я не согласен с вашим комментарием, что это не вопрос программирования. В своем комментарии вы предполагаете, что существует только одна форма лемматизации с использованием поиска по словарю, но есть и другие формы, основанные на правилах. Итак, я полагаю, что часть программирования не так проста, как вы думаете. Я согласен с любым ответом, который может выполнять лемматизацию, особенно в R, будь то словарь на основе или на основе правил. Но единственным ограничением является то, что обработка огромного корпуса текста не должна замедляться.   -  person StrikeR    schedule 03.02.2015
comment
@StrikeR, ладно, у вас проблемы с реализацией этих правил? Это вопрос программирования. У вас возникли проблемы с внедрением решения на основе словаря? Это тоже будет вопрос программирования. Это ни то, ни другое.   -  person eddi    schedule 03.02.2015


Ответы (6)


Здравствуйте, вы можете попробовать пакет koRpus, который позволяет использовать Treetagger:

tagged.results <- treetag(c("run", "ran", "running"), treetagger="manual", format="obj",
                      TT.tknz=FALSE , lang="en",
                      TT.options=list(path="./TreeTagger", preset="en"))
[email protected]

##     token tag lemma lttr wclass                               desc stop stem
## 1     run  NN   run    3   noun             Noun, singular or mass   NA   NA
## 2     ran VVD   run    3   verb                   Verb, past tense   NA   NA
## 3 running VVG   run    7   verb Verb, gerund or present participle   NA   NA

См. Столбец lemma для получения результата, который вы запрашиваете.

person Victorp    schedule 04.02.2015
comment
Спасибо, Виктор. Этот ответ мне помог. Но я все еще работаю над этим. Хотел бы подождать еще 2 дня, чтобы найти другие решения и принять это, если не будет лучшего ответа. - person StrikeR; 04.02.2015
comment
Нет проблем, я понимаю, использовать внешнее ПО может быть непросто. - person Victorp; 04.02.2015

Как упоминалось в предыдущем сообщении, функция lemmatize_words () из пакета R texttem может выполнить это и дать вам то, что я понимаю как желаемые результаты:

library(textstem)
vector <- c("run", "ran", "running")
lemmatize_words(vector)

## [1] "run" "run" "run"
person Andy    schedule 08.11.2017

@Andy и @Arunkumar правы, когда говорят, что библиотека texttem может использоваться для выполнения стемминга и / или лемматизации. Однако lemmatize_words () будет работать только с вектором слов. Но в корпусе у нас нет вектора слов; у нас есть строки, каждая из которых является содержимым документа. Следовательно, чтобы выполнить лемматизацию корпуса, вы можете использовать функцию lemmatize_strings () в качестве аргумента tm_map () пакета tm.

> corpus[[1]]
[1] " earnest roughshod document serves workable primer regions recent history make 
terrific th-grade learning tool samuel beckett applied iranian voting process bard 
black comedy willie loved another trumpet blast may new mexican cinema -bornin "
> corpus <- tm_map(corpus, lemmatize_strings)
> corpus[[1]]
[1] "earnest roughshod document serve workable primer region recent history make 
terrific th - grade learn tool samuel beckett apply iranian vote process bard black 
comedy willie love another trumpet blast may new mexican cinema - bornin"

Не забудьте запустить следующую строку кода после выполнения лемматизации:

> corpus <- tm_map(corpus, PlainTextDocument)

Это связано с тем, что для создания матрицы документа-термина вам необходимо иметь объект типа PlainTextDocument, который изменяется после использования lemmatize_strings () (точнее, объект корпуса не содержит содержимого и метаданных каждый документ больше - теперь это просто структура, содержащая содержимое документов; это не тот тип объекта, который DocumentTermMatrix () принимает в качестве аргумента).

Надеюсь это поможет!

person Harshit    schedule 12.07.2018

Может быть, вам достаточно стемминга? Типичные задачи обработки естественного языка обходятся рамочными текстами. Вы можете найти несколько пакетов в CRAN Task View of NLP: http://cran.r-project.org/web/views/NaturalLanguageProcessing.html

Если вам действительно требуется что-то более сложное, существуют специальные решения, основанные на отображении предложений в нейронные сети. Насколько мне известно, для этого требуется огромное количество обучающих данных. Существует множество открытого программного обеспечения, созданного и предоставленного Stanford NLP Group.

Если вы действительно хотите вникнуть в тему, вы можете покопаться в архивах событий, связанных с той же Stanford NLP Group публикации. Есть несколько книг по этой теме.

person LauriK    schedule 03.02.2015
comment
В настоящее время я использую стемминг для своего корпуса, но на самом деле я ищу лемматизацию, и я хочу сравнить, насколько хорошо будут улучшены результаты (скептически), когда я использую лемматизацию вместо стемминга. Спасибо за информацию. - person StrikeR; 04.02.2015

Я думаю, что ответы здесь немного устарели. Теперь вы должны использовать пакет R udpipe, доступный по адресу https://CRAN.R-project.org/package=udpipe - см. https://github.com/bnosac/udpipe или документы на https://bnosac.github.io/udpipe/en

Обратите внимание на разницу между словом «встреча» (СУЩЕСТВИТЕЛЬНОЕ) и словом «встретиться» (ГЛАГОЛ) в следующем примере при выполнении лемматизации и при выполнении стемминга, а также досадное примешивание слова «кто-то» к слову «кто-то» при выполнении стемминга.

library(udpipe)
x <- c(doc_a = "In our last meeting, someone said that we are meeting again tomorrow",
       doc_b = "It's better to be good at being the best")
anno <- udpipe(x, "english")
anno[, c("doc_id", "sentence_id", "token", "lemma", "upos")]
#>    doc_id sentence_id    token    lemma  upos
#> 1   doc_a           1       In       in   ADP
#> 2   doc_a           1      our       we  PRON
#> 3   doc_a           1     last     last   ADJ
#> 4   doc_a           1  meeting  meeting  NOUN
#> 5   doc_a           1        ,        , PUNCT
#> 6   doc_a           1  someone  someone  PRON
#> 7   doc_a           1     said      say  VERB
#> 8   doc_a           1     that     that SCONJ
#> 9   doc_a           1       we       we  PRON
#> 10  doc_a           1      are       be   AUX
#> 11  doc_a           1  meeting     meet  VERB
#> 12  doc_a           1    again    again   ADV
#> 13  doc_a           1 tomorrow tomorrow  NOUN
#> 14  doc_b           1       It       it  PRON
#> 15  doc_b           1       's       be   AUX
#> 16  doc_b           1   better   better   ADJ
#> 17  doc_b           1       to       to  PART
#> 18  doc_b           1       be       be   AUX
#> 19  doc_b           1     good     good   ADJ
#> 20  doc_b           1       at       at SCONJ
#> 21  doc_b           1    being       be   AUX
#> 22  doc_b           1      the      the   DET
#> 23  doc_b           1     best     best   ADJ
lemmatisation <- paste.data.frame(anno, term = "lemma", 
                                  group = c("doc_id", "sentence_id"))
lemmatisation
#>   doc_id sentence_id
#> 1  doc_a           1
#> 2  doc_b           1
#>                                                             lemma
#> 1 in we last meeting , someone say that we be meet again tomorrow
#> 2                          it be better to be good at be the best

library(SnowballC)
tokens   <- strsplit(x, split = "[[:space:][:punct:]]+")
stemming <- lapply(tokens, FUN = function(x) wordStem(x, language = "en"))
stemming
#> $doc_a
#>  [1] "In"       "our"      "last"     "meet"     "someon"   "said"    
#>  [7] "that"     "we"       "are"      "meet"     "again"    "tomorrow"
#> 
#> $doc_b
#>  [1] "It"     "s"      "better" "to"     "be"     "good"   "at"     "be"    
#>  [9] "the"    "best"
person user13818093    schedule 08.12.2020

Лемматизацию можно легко выполнить в R с помощью пакета textStem.
Шаги:
1) Установите texttem
2) Загрузите пакет с помощью library(textstem)
3) stem_word=lemmatize_words(word, dictionary = lexicon::hash_lemmas)
где stem_word - результат лемматизации а слово - это входное слово.

person Arunkumar CR    schedule 22.08.2017
comment
Это не очень хороший пример кода. Он даже не отформатирован должным образом. Как применить его к объекту VCorpus? - person wordsforthewise; 01.11.2017