NLTK считает, что императивы являются существительными
Я использую pos_tagger на рецептах. У меня проблема в том, что pos_tagger возвращает, что слова в императивном времени являются существительными, не должны ли они быть глаголами? Например:
С входом:
combine 1 1/2 cups floud, 3/4 cup sugar, salt and baking powder
Выход:
[('combine', 'NN'), ('1', 'CD'), ('1/2', 'CD'), ('cups', 'NNS'), ('floud', 'VBD'), (',', ','), ('3/4', 'CD'), ('cup', 'NN'), ('sugar', 'NN'), (',', ','), ('salt', 'NN'), ('and', 'CC'), ('baking', 'VBG'), ('powder', 'NN')]
Вот код, который я использую для этого:
def part_of_speech(self,input_sentance):
text = nltk.word_tokenize(input_sentance)
return nltk.pos_tag(text)
Разве "объединение" не должно быть помечено как глагол? Это вина НЛТК? Или я что-то не так делаю?
5 ответов
То, что вы видите, является очень распространенной проблемой в традиционной статистической обработке естественного языка (NLP). Короче говоря, данные, на которых вы используете теггер, не похожи на данные, на которых они были обучены. NLTK не документирует детали, но, насколько мне известно, тегер по умолчанию обучен на статьях Wall Street Journal, Brown Corpus или какой-то их комбинации. Эти корпуса содержат очень мало императивов, поэтому, когда вы даете им данные с императивами, это не делает правильную вещь.
Хорошим долгосрочным решением было бы исправить метки для большого набора рецептов и обучить исправленным данным, чтобы таким образом решить проблему несоответствия между данными обучения и тестирования. Это, однако, огромный объем работы. В идеале корпус с большим количеством императивов уже существовал бы; Моя исследовательская группа изучила это, и мы не нашли подходящую, хотя мы находимся в процессе ее создания.
Гораздо более простое решение, которое я использовал в недавнем проекте, который требовал правильного понимания императивов, состоит в том, чтобы просто отметить, какие императивы вам нужны, и заставить теги для этих слов быть правильными.
Поэтому в приведенном ниже примере я составил словарь, в котором говорится, что "объединять" следует рассматривать как глагол, а затем использовал понимание списка для изменения тегов.
tagged_words = [('combine', 'NN'), ('1', 'CD'), ('1/2', 'CD'), ('cups', 'NNS'), ('flour', 'VBD')]
force_tags = {'combine': 'VB'}
new_tagged_words = [(word, force_tags.get(word, tag)) for word, tag in tagged_words]
Содержимое new_tagged_words теперь имеет оригинальные теги, за исключением того, что они менялись везде, где была запись в force_tags.
>>> new_tagged_words
[('combine', 'VB'), ('1', 'CD'), ('1/2', 'CD'), ('cups', 'NNS'), ('flour', 'VBD')]
Это решение требует от вас сказать, какие слова вы хотите навязать глаголам. Это далеко от идеала, но лучшего общего решения не существует.
Обучение на императивных корпусах было бы лучшим вариантом. Но если у вас нет времени или вы не думаете, что усилия того стоят, вот простое решение (скорее хак): просто ставьте местоимение типа "они" перед каждым предложением (что, как вы уверены, обязательно). Теперь nltk отлично работает с тегером по умолчанию.
"Объединить" в карту существительного может быть из-за того, что он думает, что это существительное. Например, комбайн. Я предполагаю, что вы должны настроить алгоритм существительного для вашего варианта использования или изменить / изменить слово корпус.
Попробуйте Stanford POS tagger.
Мне повезло больше с этим. Он был обучен более императивным предложениям по сравнению со стандартным тегом NLTK.
Также докеризованный в https://hub.docker.com/r/cuzzo/stanford-pos-tagger/.
например
Follow us on Instagram
VB PRP IN NN
>>> from nltk import pos_tag, word_tokenize
>>> def imperative_pos_tag(sent):
... return pos_tag(['He']+sent)[1:]
...
>>> sent1 = 'combine 1 1/2 cups floud, 3/4 cup sugar, salt and baking powder'
>>> imperative_pos_tag(word_tokenize(sent1))
[('combine', 'VBD'), ('1', 'CD'), ('1/2', 'CD'), ('cups', 'NNS'), ('floud', 'VBD'), (',', ','), ('3/4', 'CD'), ('cup', 'NN'), ('sugar', 'NN'), (',', ','), ('salt', 'NN'), ('and', 'CC'), ('baking', 'VBG'), ('powder', 'NN')]
Также обратите внимание на то, что Python NLTK pos_tag не возвращает правильный тег части речи, а NLTK определяет глагол как существительное в императивах.