Вычисление имен Norton Recognizer (NER) в Stanford Nancy из формата NLTK

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

[(u'Remaking', u'O'), (u'The', u'O'), (u'Republican', u'ORGANIZATION'), (u'Party', u'ORGANIZATION')] 

Можно ли объединить все вместе, используя это? Я хочу так:

 u'Remaking'/ u'O', u'The'/u'O', (u'Republican', u'Party')/u'ORGANIZATION' 

Благодаря!

4 Solutions collect form web for “Вычисление имен Norton Recognizer (NER) в Stanford Nancy из формата NLTK”

Вы можете использовать стандартный способ NLTK для представления фрагментов, используя nltk.Tree . Это может означать, что вам нужно немного изменить свое представление.

То, что я обычно делаю, представляет собой предложения, помеченные NER, в виде списков триплетов :

 sentence = [('Andrew', 'NNP', 'PERSON'), ('is', 'VBZ', 'O'), ('part', 'NN', 'O'), ('of', 'IN', 'O'), ('the', 'DT', 'O'), ('Republican', 'NNP', 'ORGANIZATION'), ('Party', 'NNP', 'ORGANIZATION'), ('in', 'IN', 'O'), ('Dallas', 'NNP', 'LOCATION')] 

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

 from nltk import Tree def IOB_to_tree(iob_tagged): root = Tree('S', []) for token in iob_tagged: if token[2] == 'O': root.append((token[0], token[1])) else: try: if root[-1].label() == token[2]: root[-1].append((token[0], token[1])) else: root.append(Tree(token[2], [(token[0], token[1])])) except: root.append(Tree(token[2], [(token[0], token[1])])) return root sentence = [('Andrew', 'NNP', 'PERSON'), ('is', 'VBZ', 'O'), ('part', 'NN', 'O'), ('of', 'IN', 'O'), ('the', 'DT', 'O'), ('Republican', 'NNP', 'ORGANIZATION'), ('Party', 'NNP', 'ORGANIZATION'), ('in', 'IN', 'O'), ('Dallas', 'NNP', 'LOCATION')] print IOB_to_tree(sentence) 

Изменение вида представления имеет смысл, потому что вам наверняка нужны метки POS для тегов NER.

Конечный результат должен выглядеть так:

 (S (PERSON Andrew/NNP) is/VBZ part/NN of/IN the/DT (ORGANIZATION Republican/NNP Party/NNP) in/IN (LOCATION Dallas/NNP)) 

Он выглядит долго, но он делает работу:

 ner_output = [(u'Remaking', u'O'), (u'The', u'O'), (u'Republican', u'ORGANIZATION'), (u'Party', u'ORGANIZATION')] chunked, pos = [], "" for i, word_pos in enumerate(ner_output): word, pos = word_pos if pos in ['PERSON', 'ORGANIZATION', 'LOCATION'] and pos == prev_tag: chunked[-1]+=word_pos else: chunked.append(word_pos) prev_tag = pos clean_chunked = [tuple([" ".join(wordpos[::2]), wordpos[-1]]) if len(wordpos)!=2 else wordpos for wordpos in chunked] print clean_chunked 

[вне]:

 [(u'Remaking', u'O'), (u'The', u'O'), (u'Republican Party', u'ORGANIZATION')] 

Больше подробностей:

Первый для цикла «с памятью» достигает чего-то вроде этого:

 [(u'Remaking', u'O'), (u'The', u'O'), (u'Republican', u'ORGANIZATION', u'Party', u'ORGANIZATION')] 

Вы поймете, что все имена Enitties будут содержать более двух элементов в кортеже, и вы хотите, чтобы слова были как элементы в списке, то есть 'Republican Party' в (u'Republican', u'ORGANIZATION', u'Party', u'ORGANIZATION') , поэтому вы сделаете что-то подобное, чтобы получить четные элементы:

 >>> x = [0,1,2,3,4,5,6] >>> x[::2] [0, 2, 4, 6] >>> x[1::2] [1, 3, 5] 

Затем вы также поняли, что последний элемент в корте NE – это тег, который вы хотите, так что вы будете делать `

 >>> x = (u'Republican', u'ORGANIZATION', u'Party', u'ORGANIZATION') >>> x[::2] (u'Republican', u'Party') >>> x[-1] u'ORGANIZATION' 

Это немного ad-hoc и vebose, но я надеюсь, что это поможет. И вот это функция, Благословенное Рождество:

 ner_output = [(u'Remaking', u'O'), (u'The', u'O'), (u'Republican', u'ORGANIZATION'), (u'Party', u'ORGANIZATION')] def rechunk(ner_output): chunked, pos = [], "" for i, word_pos in enumerate(ner_output): word, pos = word_pos if pos in ['PERSON', 'ORGANIZATION', 'LOCATION'] and pos == prev_tag: chunked[-1]+=word_pos else: chunked.append(word_pos) prev_tag = pos clean_chunked = [tuple([" ".join(wordpos[::2]), wordpos[-1]]) if len(wordpos)!=2 else wordpos for wordpos in chunked] return clean_chunked print rechunk(ner_output) 

Это на самом деле происходит в следующем выпуске CoreNLP под названием MentionsAnnotator . Скорее всего, он не будет доступен напрямую из NLTK, если только люди NLTK не захотят его поддерживать, а также стандартный интерфейс Stanford NER.

В любом случае, на данный момент вам придется скопировать код, с которым я связан (который использует LabeledChunkIdentifier для грязной работы) или написать собственный постпроцессор в Python.

Вот еще одна краткая реализация для группировки результатов Stanford NER с использованием итератора group itertools :

 def grouptags(tags, ignore="O", join=" "): from itertools import groupby for c,g in groupby(tags, lambda t: t[1]): if ignore is None or c != ignore: if join is None: entity = [e for e,_ in g] else: entity = join.join(e for e,_ in g) yield(c, entity) 

Функция grouptags имеет два варианта:

  • ignore : указать класс, который игнорируется и исключается из вывода (по умолчанию: «O»). Если «Нет», все объекты возвращаются.
  • join : укажите символ, используемый для соединения частей (по умолчанию: «»). Если « Нет» , части возвращаются как список.
 
Interesting Posts for Van-Lav

Cython: ImportError: нет модуля с именем 'myModule': как вызвать модуль cython, содержащий cimport для другого контура cython?

Как организовать проект python, который содержит несколько пакетов, чтобы каждый файл в пакете можно было запускать отдельно?

Разбиение списка на размеры, указанные другим списком

массив numpy с использованием длинного типа python

Как удалить список строк из фреймворка Pandas?

Объединение списков в один

PyQt передает параметр в слот при подключении к сигналу

Приоритет оператора присваивания Python – (a, b) = a = {}, 5

Django Не удается обновить запрос после того, как был сделан фрагмент

Изменение регулярного выражения Python

Грамматическая проверка для области текста html

Измените тип идентификатора пользователя на UUID

Повторное использование части шаблона Regex

Проблемы с заказчиком LIBFFI Heroku buildpack

Как создать символическую ссылку в zipfile в python

Python - лучший язык программирования в мире.