Пользовательский токенизатор и тегировщик nltk

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

  • Следует указать дату и время в абзаце и пометить их как ДАТА и ВРЕМЯ.
  • Должен определять известные фразы в абзаце и помечать их как CUSTOM.
  • И остальное содержимое должно быть токенизировано должно быть токенизировано функциями word_tokenize и pos_tag nltk по умолчанию?

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

"They all like to go there on 5th November 2010, but I am not interested."

должны быть помечены и размечены следующим образом в случае, если пользовательская фраза "Мне это не интересно".

[('They', 'PRP'), ('all', 'VBP'), ('like', 'IN'), ('to', 'TO'), ('go', 'VB'), 
('there', 'RB'), ('on', 'IN'), ('5th November 2010', 'DATE'), (',', ','), 
('but', 'CC'), ('I am not interested', 'CUSTOM'), ('.', '.')]

Будут полезны любые предложения.


person Software Enthusiastic    schedule 14.10.2010    source источник
comment
как вы подошли к этой проблеме? У меня есть аналогичный вариант использования, в котором мне нужно пометить известные фразы в разных предложениях с помощью настраиваемых ТЕГОВ.   -  person AgentX    schedule 17.07.2017


Ответы (2)


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

s = "They all like to go there on 5th November 2010, but I am not interested."

DATE = re.compile(r'^[1-9][0-9]?(th|st|rd)? (January|...)( [12][0-9][0-9][0-9])?$')

def custom_tagger(sentence):
    tagged = pos_tag(word_tokenize(sentence))
    phrase = []
    date_found = False

    i = 0
    while i < len(tagged):
        (w,t) = tagged[i]
        phrase.append(w)
        in_date = DATE.match(' '.join(phrase))
        date_found |= bool(in_date)
        if date_found and not in_date:          # end of date found
            yield (' '.join(phrase[:-1]), 'DATE')
            phrase = []
            date_found = False
        elif date_found and i == len(tagged)-1:    # end of date found
            yield (' '.join(phrase), 'DATE')
            return
        else:
            i += 1
            if not in_date:
                yield (w,t)
                phrase = []

Задача: разверните DATE re, вставьте код для поиска CUSTOM фраз, усложните поиск, сопоставив POS-теги и жетоны, и решите, следует ли считать дату 5th сам по себе. (Вероятно, нет, поэтому отфильтруйте даты длины один, которые содержат только порядковый номер.)

person Fred Foo    schedule 14.10.2010

Вероятно, вам следует выполнить фрагментацию с помощью nltk.RegexpParser для достижения вашей цели.

Ссылка: http://nltk.googlecode.com/svn/trunk/doc/book/ch07.html#code-chunker1

person Neodawn    schedule 14.10.2010