Подтвердить что ты не робот

Пользовательская пометка с помощью nltk

Я пытаюсь создать небольшой англоязычный язык для задания задач. Основная идея состоит в том, чтобы разделить утверждение на глаголы и существительные-фразы, к которым должны относиться эти глаголы. Я работаю с nltk, но не получаю ожидаемых результатов, например:

>>> nltk.pos_tag(nltk.word_tokenize("select the files and copy to harddrive'"))
[('select', 'NN'), ('the', 'DT'), ('files', 'NNS'), ('and', 'CC'), ('copy', 'VB'), ('to', 'TO'), ("harddrive'", 'NNP')]
>>> nltk.pos_tag(nltk.word_tokenize("move the files to harddrive'"))
[('move', 'NN'), ('the', 'DT'), ('files', 'NNS'), ('to', 'TO'), ("harddrive'", 'NNP')]
>>> nltk.pos_tag(nltk.word_tokenize("copy the files to harddrive'"))
[('copy', 'NN'), ('the', 'DT'), ('files', 'NNS'), ('to', 'TO'), ("harddrive'", 'NNP')]

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

Так или иначе, мой вопрос один из: Есть ли лучший теггер для этого типа грамматики? Есть ли способ весить существующий теггер в сторону использования формы глагола чаще, чем форма существительного? Есть ли способ тренировать теггер? Есть ли лучший способ вообще?

4b9b3361

Ответ 1

Одним из решений является создание ручного UnigramTagger, который отсылается к тегере NLTK. Что-то вроде этого:

>>> import nltk.tag, nltk.data
>>> default_tagger = nltk.data.load(nltk.tag._POS_TAGGER)
>>> model = {'select': 'VB'}
>>> tagger = nltk.tag.UnigramTagger(model=model, backoff=default_tagger)

Затем вы получаете

>>> tagger.tag(['select', 'the', 'files'])
[('select', 'VB'), ('the', 'DT'), ('files', 'NNS')]

Этот же метод может работать для неанглийских языков, если у вас есть соответствующий теггер по умолчанию. Вы можете обучать свои собственные тегеры с помощью train_tagger.py из nltk-trainer и соответствующего корпуса.

Ответ 2

Ответ Джейкоба на месте. Однако, чтобы расширить его, вы можете обнаружить, что вам нужно больше, чем просто униграммы.

Например, рассмотрим три предложения:

select the files
use the select function on the sockets
the select was good

Здесь слово "select" используется как глагол, прилагательное и существительное соответственно. Агрегистр unigram не сможет моделировать это. Даже тегатор bigram не может справиться с этим, потому что два случая имеют одно и то же предыдущее слово (т.е. "The" ). Для правильного обращения с этим случаем вам понадобится триггер-теггер.

import nltk.tag, nltk.data
from nltk import word_tokenize
default_tagger = nltk.data.load(nltk.tag._POS_TAGGER)

def evaluate(tagger, sentences):
    good,total = 0,0.
    for sentence,func in sentences:
        tags = tagger.tag(nltk.word_tokenize(sentence))
        print tags
        good += func(tags)
        total += 1
    print 'Accuracy:',good/total

sentences = [
    ('select the files', lambda tags: ('select', 'VB') in tags),
    ('use the select function on the sockets', lambda tags: ('select', 'JJ') in tags and ('use', 'VB') in tags),
    ('the select was good', lambda tags: ('select', 'NN') in tags),
]

train_sents = [
    [('select', 'VB'), ('the', 'DT'), ('files', 'NNS')],
    [('use', 'VB'), ('the', 'DT'), ('select', 'JJ'), ('function', 'NN'), ('on', 'IN'), ('the', 'DT'), ('sockets', 'NNS')],
    [('the', 'DT'), ('select', 'NN'), ('files', 'NNS')],
]

tagger = nltk.TrigramTagger(train_sents, backoff=default_tagger)
evaluate(tagger, sentences)
#model = tagger._context_to_tag

Обратите внимание: вы можете использовать NLTK NgramTagger для обучения тегов с использованием произвольно большого количества n-граммов, но обычно вы не используете" t увеличивать производительность после триграмм.

Ответ 3

См. ответ Джейкоба.

В более поздних версиях (по крайней мере, nltk 3.2) nltk.tag._POS_TAGGER не существует. Тегеры по умолчанию обычно загружаются в каталог nltk_data/taggers/, например:

>>> import nltk
>>> nltk.download('maxent_treebank_pos_tagger') 

Использование выглядит следующим образом.

>>> import nltk.tag, nltk.data
>>> tagger_path = '/path/to/nltk_data/taggers/maxent_treebank_pos_tagger/english.pickle'
>>> default_tagger = nltk.data.load(tagger_path)
>>> model = {'select': 'VB'}
>>> tagger = nltk.tag.UnigramTagger(model=model, backoff=default_tagger)

См. также: Как выполнить тегирование POS с помощью теггера POS NLTK в Python.

Ответ 4

Ответ Bud правильный. Кроме того, согласно эта ссылка,

если ваши пакеты nltk_data были правильно установлены, тогда NLTK знает, где они находятся в вашей системе, и вам не нужно передавать абсолютный путь.

Смысл, вы можете просто сказать

tagger_path = '/path/to/nltk_data/taggers/maxent_treebank_pos_tagger/english.pickle'
default_tagger = nltk.data.load(tagger_path)