пользовательские теги с помощью nltk - PullRequest
25 голосов
/ 07 мая 2011

Я пытаюсь создать небольшой англоязычный язык для задания задач.Основная идея состоит в том, чтобы разбить утверждение на глаголы и существительные, к которым эти глаголы должны применяться.Я работаю с 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')]

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

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

Ответы [ 4 ]

28 голосов
/ 07 мая 2011

Одним из решений является создание руководства 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 и соответствующий корпус.

22 голосов
/ 04 ноября 2011

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

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

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

Здесь слово «выбор» используется как глагол, прилагательное и существительное соответственно. Unigram Tagger не сможет моделировать это. Даже биграмный тегер не может справиться с этим, потому что два случая имеют одно и то же предшествующее слово (то есть "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-грамм, но обычно вы не получаете большого увеличения производительности после триграмм.

6 голосов
/ 14 декабря 2016

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

В более поздних версиях (по крайней мере, 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 .

2 голосов
/ 16 апреля 2017

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

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

Значит, вы можете просто сказать

tagger_path = '/path/to/nltk_data/taggers/maxent_treebank_pos_tagger/english.pickle'
default_tagger = nltk.data.load(tagger_path)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...