Python NLTK pos_tag не возвращает правильный тег части речи
Имея это:
text = word_tokenize("The quick brown fox jumps over the lazy dog")
И работает:
nltk.pos_tag(text)
Я получил:
[('The', 'DT'), ('quick', 'NN'), ('brown', 'NN'), ('fox', 'NN'), ('jumps', 'NNS'), ('over', 'IN'), ('the', 'DT'), ('lazy', 'NN'), ('dog', 'NN')]
Это неверно Теги для quick brown lazy
в предложении должно быть:
('quick', 'JJ'), ('brown', 'JJ') , ('lazy', 'JJ')
Тестирование этого через их онлайн-инструмент дает тот же результат; quick
, brown
а также fox
должны быть прилагательными, а не существительными.
3 ответа
Короче говоря:
НЛТК не идеален. На самом деле ни одна модель не идеальна.
Замечания:
Начиная с версии NLTK 3.1, по умолчанию pos_tag
функция больше не является старым английским рассолом MaxEnt.
Теперь это тегер персептрона из реализации @Honnibal, см. nltk.tag.pos_tag
>>> import inspect
>>> print inspect.getsource(pos_tag)
def pos_tag(tokens, tagset=None):
tagger = PerceptronTagger()
return _pos_tag(tokens, tagset, tagger)
Все-таки лучше, но не идеально
>>> from nltk import pos_tag
>>> pos_tag("The quick brown fox jumps over the lazy dog".split())
[('The', 'DT'), ('quick', 'JJ'), ('brown', 'NN'), ('fox', 'NN'), ('jumps', 'VBZ'), ('over', 'IN'), ('the', 'DT'), ('lazy', 'JJ'), ('dog', 'NN')]
В какой-то момент, если кто-то хочетTL;DR
решения, см. https://github.com/alvations/nltk_cli
В длинных:
Попробуйте использовать другой тегер (см. https://github.com/nltk/nltk/tree/develop/nltk/tag), например:
- HunPos
- Стэнфордский POS
- сено
Использование по умолчанию MaxEnt POS tagger от NLTK, т.е.nltk.pos_tag
:
>>> from nltk import word_tokenize, pos_tag
>>> text = "The quick brown fox jumps over the lazy dog"
>>> pos_tag(word_tokenize(text))
[('The', 'DT'), ('quick', 'NN'), ('brown', 'NN'), ('fox', 'NN'), ('jumps', 'NNS'), ('over', 'IN'), ('the', 'DT'), ('lazy', 'NN'), ('dog', 'NN')]
Использование Stanford POS tagger:
$ cd ~
$ wget http://nlp.stanford.edu/software/stanford-postagger-2015-04-20.zip
$ unzip stanford-postagger-2015-04-20.zip
$ mv stanford-postagger-2015-04-20 stanford-postagger
$ python
>>> from os.path import expanduser
>>> home = expanduser("~")
>>> from nltk.tag.stanford import POSTagger
>>> _path_to_model = home + '/stanford-postagger/models/english-bidirectional-distsim.tagger'
>>> _path_to_jar = home + '/stanford-postagger/stanford-postagger.jar'
>>> st = POSTagger(path_to_model=_path_to_model, path_to_jar=_path_to_jar)
>>> text = "The quick brown fox jumps over the lazy dog"
>>> st.tag(text.split())
[(u'The', u'DT'), (u'quick', u'JJ'), (u'brown', u'JJ'), (u'fox', u'NN'), (u'jumps', u'VBZ'), (u'over', u'IN'), (u'the', u'DT'), (u'lazy', u'JJ'), (u'dog', u'NN')]
Использование HunPOS(ПРИМЕЧАНИЕ: кодировка по умолчанию ISO-8859-1, а не UTF8):
$ cd ~
$ wget https://hunpos.googlecode.com/files/hunpos-1.0-linux.tgz
$ tar zxvf hunpos-1.0-linux.tgz
$ wget https://hunpos.googlecode.com/files/en_wsj.model.gz
$ gzip -d en_wsj.model.gz
$ mv en_wsj.model hunpos-1.0-linux/
$ python
>>> from os.path import expanduser
>>> home = expanduser("~")
>>> from nltk.tag.hunpos import HunposTagger
>>> _path_to_bin = home + '/hunpos-1.0-linux/hunpos-tag'
>>> _path_to_model = home + '/hunpos-1.0-linux/en_wsj.model'
>>> ht = HunposTagger(path_to_model=_path_to_model, path_to_bin=_path_to_bin)
>>> text = "The quick brown fox jumps over the lazy dog"
>>> ht.tag(text.split())
[('The', 'DT'), ('quick', 'JJ'), ('brown', 'JJ'), ('fox', 'NN'), ('jumps', 'NNS'), ('over', 'IN'), ('the', 'DT'), ('lazy', 'JJ'), ('dog', 'NN')]
Использование Senna(убедитесь, что у вас последняя версия NLTK, в API были внесены некоторые изменения):
$ cd ~
$ wget http://ronan.collobert.com/senna/senna-v3.0.tgz
$ tar zxvf senna-v3.0.tgz
$ python
>>> from os.path import expanduser
>>> home = expanduser("~")
>>> from nltk.tag.senna import SennaTagger
>>> st = SennaTagger(home+'/senna')
>>> text = "The quick brown fox jumps over the lazy dog"
>>> st.tag(text.split())
[('The', u'DT'), ('quick', u'JJ'), ('brown', u'JJ'), ('fox', u'NN'), ('jumps', u'VBZ'), ('over', u'IN'), ('the', u'DT'), ('lazy', u'JJ'), ('dog', u'NN')]
Или попробуйте создать лучший POS-тегер:
- Ngram Tagger: http://streamhacker.com/2008/11/03/part-of-speech-tagging-with-nltk-part-1/
- Affix / Regex Tagger: http://streamhacker.com/2008/11/10/part-of-speech-tagging-with-nltk-part-2/
- Создайте свой собственный Brill (прочитайте код, это довольно забавный теггер, http://www.nltk.org/_modules/nltk/tag/brill.html), см. Http://streamhacker.com/2008/12/03/ неполный из-речи-мечение-с- NLTK-часть-3 /
- Перцептрон Tagger: https://honnibal.wordpress.com/2013/09/11/a-good-part-of-speechpos-tagger-in-about-200-lines-of-python/
- LDA Tagger: http://scm.io/blog/hack/2015/02/lda-intentions/
Жалуется наpos_tag
Точность на стеке потока включает в себя:
- POS маркировка - NLTK считает существительное прилагательным
- Python NLTK POS-тегер не работает должным образом
- Как получить лучшие результаты, используя NLTK pos tag
- pos_tag в NLTK неправильно помечает предложения
Вопросы о NLTK HunPos включают в себя:
- Как пометить текстовые файлы с помощью hunpos в nltk?
- Кто-нибудь знает как настроить класс обертки hunpos на nltk?
Проблемы с NLTK и Stanford POS tagger включают в себя:
- Проблемы с импортом Стэнфордского Pos Tagger в NLTK
- Сбои Java-команд в NLTK Stanford POS Tagger
- Ошибка использования Stanford POS Tagger в NLTK Python
- Как улучшить скорость с Stanford NLP Tagger и NLTK
- NLTK Stanford Pos Tagger ошибка: команда Java не удалось
- Создание и использование StanfordTagger в NLTK
- Запуск Stanford POS tagger в NLTK приводит к "неправильному приложению Win32" в Windows
Такие решения, как переход на теггер Stanford, Senna или HunPOS, определенно дадут результаты, но вот гораздо более простой способ поэкспериментировать с различными тегами, которые также включены в NLTK.
По умолчанию POS-теггер в NTLK сейчас - это усредненный теггер-перцептрон. Вот функция, которая выберет вместо этого Maxent Treebank Tagger:
def treebankTag(text)
words = nltk.word_tokenize(text)
treebankTagger = nltk.data.load('taggers/maxent_treebank_pos_tagger/english.pickle')
return treebankTagger.tag(words)
Я обнаружил, что усредненный предварительно обученный теггер перцептрона в NLTK склонен рассматривать некоторые прилагательные как существительные, как в вашем примере. Маркер банка деревьев получил больше подходящих для меня прилагательных.
def tagPOS(textcontent, taggedtextcontent, defined_tags):# Напишите здесь свой код token = nltk.word_tokenize(textcontent) nltk_pos_tags = nltk.pos_tag (token)
unigram_pos_tag = nltk.UnigramTagger(model=defined_tags).tag(token)
tagged_pos_tag = [ nltk.tag.str2tuple(word) for word in taggedtextcontent.split() ]
return (nltk_pos_tags,tagged_pos_tag,unigram_pos_tag)