Пространственная лемматизация одного слова - PullRequest
1 голос
/ 08 января 2020

Я пытаюсь получить лемматизированную версию одного слова. Есть ли способ использовать "spacy" (библиотека fantasti c python NLP) для этого.

Ниже приведен код, который я пробовал, но это не работает):

from spacy.lemmatizer import Lemmatizer
from spacy.lookups import Lookups
lookups = Lookups()
lemmatizer = Lemmatizer(lookups)
word = "ducks"
lemmas = lemmatizer.lookup(word)
print(lemmas)

Результат, на который я надеялся, заключался в том, что слово «утки» (множественное число) приведет к «утке» (единственное число). К сожалению, возвращается «ducks» (множественное число).

Есть ли способ сделать это?

ПРИМЕЧАНИЕ. Я понимаю, что могу обработать целую строку слов из документа (nlp ( document)), затем найдите требуемый токен и получите его лемму (token.lemma_), но слова, которые мне нужно лемматизировать, несколько динамичны c и не могут быть обработаны как большой документ.

Ответы [ 3 ]

2 голосов
/ 08 января 2020

Я думаю, что вам не хватает той части, где вы используете базу данных spaCy в качестве ссылки для лемматизации. Если вы видите изменения, которые я внес в ваш код ниже, и предоставили вывод. duck является правильным lemma_ для ducks.

import spacy
from spacy.lemmatizer import Lemmatizer
from spacy.lookups import Lookups
lookups = Lookups()
lemmatizer = Lemmatizer(lookups)

word = "ducks"
#load spacy core database
nlp = spacy.load('en_core_web_sm')
#run NLP on input/doc
doc = nlp(word)
#Print formatted token attributes
print("Token Attributes: \n", "token.text, token.pos_, token.tag_, token.dep_, token.lemma_")
for token in doc:
    # Print the text and the predicted part-of-speech tag
    print("{:<12}{:<12}{:<12}{:<12}{:<12}".format(token.text, token.pos_, token.tag_, token.dep_, token.lemma_))

Выход

Token Attributes: 
 token.text, token.pos_, token.tag_, token.dep_, token.lemma_
ducks       NOUN        NNS         ROOT        duck               

Лемматизация в решающей степени зависит от части речи токена. Только жетоны с одинаковой частью речи отображаются на одну и ту же лемму.

В предложении «Это сбивает с толку» confusing анализируется как прилагательное, и, следовательно, оно превращается в confusing. В предложении «я тебя с кем-то путал», напротив, confusing анализируется как глагол и переводится в confuse.

Если вы хотите, чтобы токены с разными частями речи были сопоставлены с одной и той же леммой, вы можете использовать алгоритм стволов, такой как Porter Stemming (Java), который вы можете просто вызвать на каждом жетоне.

0 голосов
/ 10 января 2020

С NLTK просто:

>>> from nltk.stem import WordNetLemmatizer
>>> wnl = WordNetLemmatizer()
>>> wnl.lemmatize('ducks')
'duck'
0 голосов
/ 08 января 2020

Если вы хотите лемматизировать один токен, попробуйте упрощенную обработку текста lib TextBlob :

from textblob import TextBlob, Word
# Lemmatize a word
w = Word('ducks')
w.lemmatize()

Вывод

> duck

Или NLTK

import nltk
from nltk.stem import SnowballStemmer
stemmer = nltk.stem.SnowballStemmer('english')
stemmer.stem('ducks')

Выход

> duck

В противном случае вы можете продолжать использовать spaCy , но после отключения parser и NER компонентов конвейера:

  • Начните с загрузки маленькой модели размером 12 МБ (Engli sh многозадачный CNN, обученный OntoNotes)
$ python -m spacy download en_core_web_sm
  • Python код
import spacy
nlp = spacy.load('en_core_web_sm', disable=['parser', 'ner']) # just keep tagger for lemmatization
" ".join([token.lemma_ for token in nlp('ducks')])

Выход

> duck
...