Использовать spacy-lookup с лемматизированным предложением? - PullRequest
0 голосов
/ 17 февраля 2019

У меня есть входные предложения, которые содержат пользовательские многословные объекты, которые мне нужно сопоставить, поэтому для этой цели я использую превосходную библиотеку spacy-lookup .Однако у него есть один недостаток;он не может распознать множественные слова в предложении, которые он имеет как сущности.Например, если я объявлю banana как сущность, а short blue bananas как предложение, он не узнает, что bananas является сущностью.Мое текущее «исправление» для этого состоит в том, чтобы сделать что-то вроде этого:

# Start by lowering inputLine (just in case) and removing any whitespace trailing/leading.
doc = nlp(inputLine.lower().strip())
# Lemmatize the words so things like bananas => banana.
words = list(map(lambda token: token.lemma_, doc))
lemmatized = ' '.join(words)

В основном запуск nlp поверх исходного предложения и связывание лемм вместе, чтобы создать новое предложение.Тем не менее, это потребовало бы от меня запуска nlp в лемматизированном предложении для извлечения сущностей с пространственным поиском, и это просто кажется ... неправильным.Я что-то упускаю в конвейере, который позволил бы spacy-lookup проверять леммы вместо оригинальных слов, и поэтому должен вызывать nlp только один раз?

Ответы [ 2 ]

0 голосов
/ 18 февраля 2019

Вы не упускаете ни одного очевидного решения, чтобы взглянуть на леммы в простом стиле.spacy-lookup говорит прямо в README (ближе к концу раздела об использовании): «spacy-lookup заботится только о тексте токена» *

Вам нужно изменить spacy-lookup, чтобы он делал то, что выхотите, около здесь :

matches = self.keyword_processor.extract_keywords(doc.text, span_info=True)

Вы могли бы потенциально изменить doc.text на что-то еще здесь (например, ' '.join([token.lemma_ for token in doc])), но тогда у вас возникнут проблемы, потому что spacy-lookup полагается насмещения символов в тексте документа для обработки диапазонов сущностей, поэтому вам придется переделать обнаружение / объединение диапазонов сущностей, чтобы он использовал смещения токенов вместо смещений символов для выравнивания сущностей с исходным текстом документа.(Это было бы выполнимо, но немного хлопотно.)

Если все, что вам нужно, это поиск сущностей, вы можете использовать spacy (или NLTK или что-то еще), чтобы сгенерировать леммы, а затем использовать flashtext самостоятельно длянайти сущности, полностью пропуская поиск.Если вам не нужен дальнейший анализ пространств, то это будет самый простой вариант.

Другие примечания:

  • spacy-lookup, похоже, имеет вариант для case- нечувствительный поиск (через опцию, переданную во flashtext)

  • , если вы хотите использовать spacy и если лемматизация spacy достаточно хороша для того, что вам нужно (проверьте внимательно!), в этом нет необходимостивместо этого использовать NLTK;Вы можете создать более быстрый конвейер, который отключит ненужные компоненты:

    nlp = spacy.load('en', disable=['tagger', 'parser', 'ner'])
    
0 голосов
/ 17 февраля 2019

Вы можете использовать WordNet lemmatizer из модуля NLTK следующим образом:

>>> import nltk
>>> from nltk.stem import WordNetLemmatizer
>>>
>>> wordnet_lemmatizer = WordNetLemmatizer()
>>> wordnet_lemmatizer.lemmatize("bananas")
banana

Итак, согласно вашему примеру, вы можете сделать что-то вроде этого:

sentence = "short blue bananas"
for word in sentence.split(" "):
    word = word.lower()
    print(wordnet_lemmatizer.lemmatize(word))

И это напечатало бы short blue banana

Если вы не знаете, как использовать nltk .., следуйте этому:

  1. Установите модуль NLTK, запустив pip install nltk
  2. откройте терминал и введите следующую команду для загрузки популярных пакетов в NLTK.
$ python
Python 3.6.5 |Anaconda, Inc.| (default, Apr 29 2018, 16:14:56) 
[GCC 7.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.

>>> import nltk
>>> nltk.download('popular')
>>> nltk.download('wordnet')
...