web-dev-qa-db-fra.com

Reconnaissance d'entité nommée NLTK dans une liste Python

J'ai utilisé le ne_chunk de NLTK pour extraire des entités nommées d'un texte:

my_sent = "WASHINGTON -- In the wake of a string of abuses by New York police officers in the 1990s, Loretta E. Lynch, the top federal prosecutor in Brooklyn, spoke forcefully about the pain of a broken trust that African-Americans felt and said the responsibility for repairing generations of miscommunication and mistrust fell to law enforcement."


nltk.ne_chunk(my_sent, binary=True)

Mais je n'arrive pas à comprendre comment sauvegarder ces entités dans une liste? Par exemple. -

print Entity_list
('WASHINGTON', 'New York', 'Loretta', 'Brooklyn', 'African')

Merci.

12
Zlo

nltk.ne_chunk renvoie un objet nltk.tree.Tree imbriqué, ce qui vous oblige à parcourir l'objet Tree pour accéder aux éléments de réseau.

Jetez un coup d’œil à Reconnaissance d’entités nommées avec expression régulière: NLTK

>>> from nltk import ne_chunk, pos_tag, Word_tokenize
>>> from nltk.tree import Tree
>>> 
>>> def get_continuous_chunks(text):
...     chunked = ne_chunk(pos_tag(Word_tokenize(text)))
...     continuous_chunk = []
...     current_chunk = []
...     for i in chunked:
...             if type(i) == Tree:
...                     current_chunk.append(" ".join([token for token, pos in i.leaves()]))
...             Elif current_chunk:
...                     named_entity = " ".join(current_chunk)
...                     if named_entity not in continuous_chunk:
...                             continuous_chunk.append(named_entity)
...                             current_chunk = []
...             else:
...                     continue
...     return continuous_chunk
... 
>>> my_sent = "WASHINGTON -- In the wake of a string of abuses by New York police officers in the 1990s, Loretta E. Lynch, the top federal prosecutor in Brooklyn, spoke forcefully about the pain of a broken trust that African-Americans felt and said the responsibility for repairing generations of miscommunication and mistrust fell to law enforcement."
>>> get_continuous_chunks(my_sent)
['WASHINGTON', 'New York', 'Loretta E. Lynch', 'Brooklyn']
28
alvas

Vous pouvez également extraire la label de chaque entité de nom dans le texte en utilisant ce code:

import nltk
for sent in nltk.sent_tokenize(sentence):
   for chunk in nltk.ne_chunk(nltk.pos_tag(nltk.Word_tokenize(sent))):
      if hasattr(chunk, 'label'):
         print(chunk.label(), ' '.join(c[0] for c in chunk))

Sortie:

GPE WASHINGTON
GPE New York
PERSON Loretta E. Lynch
GPE Brooklyn

Vous pouvez voir que Washington, New York et Brooklyn sont GPE signifie entités géo-politiques

et Loretta E. Lynch est une PERSON

8
imanzabet

Lorsque vous obtenez tree comme valeur de retour, je suppose que vous souhaitez choisir les sous-arbres étiquetés avec NE

Voici un exemple simple pour rassembler tous ceux dans une liste:

import nltk

my_sent = "WASHINGTON -- In the wake of a string of abuses by New York police officers in the 1990s, Loretta E. Lynch, the top federal prosecutor in Brooklyn, spoke forcefully about the pain of a broken trust that African-Americans felt and said the responsibility for repairing generations of miscommunication and mistrust fell to law enforcement."

parse_tree = nltk.ne_chunk(nltk.tag.pos_tag(my_sent.split()), binary=True)  # POS tagging before chunking!

named_entities = []

for t in parse_tree.subtrees():
    if t.label() == 'NE':
        named_entities.append(t)
        # named_entities.append(list(t))  # if you want to save a list of tagged words instead of a tree

print named_entities

Cela donne:

[Tree('NE', [('WASHINGTON', 'NNP')]), Tree('NE', [('New', 'NNP'), ('York', 'NNP')])]

ou sous forme de liste de listes:

[[('WASHINGTON', 'NNP')], [('New', 'NNP'), ('York', 'NNP')]]

Voir aussi: Comment naviguer dans un nltk.tree.Tree?

4
b3000

utilisez tree2conlltags depuis nltk.chunk. De plus, ne_chunk a besoin de balises pos qui identifient les jetons Word (donc nécessite Word_tokenize).

from nltk import Word_tokenize, pos_tag, ne_chunk
from nltk.chunk import tree2conlltags

sentence = "Mark and John are working at Google."
print(tree2conlltags(ne_chunk(pos_tag(Word_tokenize(sentence))
"""[('Mark', 'NNP', 'B-PERSON'), 
    ('and', 'CC', 'O'), ('John', 'NNP', 'B-PERSON'), 
    ('are', 'VBP', 'O'), ('working', 'VBG', 'O'), 
    ('at', 'IN', 'O'), ('Google', 'NNP', 'B-ORGANIZATION'), 
    ('.', '.', 'O')] """

Cela vous donnera une liste de tuples: [(token, pos_tag, name_entity_tag)]] Si cette liste n’est pas exactement ce que vous voulez, il est certainement plus facile d’analyser la liste que vous voulez hors de cette liste, puis un arbre nltk.

Code et détails de ce lien ; check it out pour plus d'informations

Edit Ajouté le document de sortie

3
elwhite

Un Tree est une liste. Les morceaux sont des sous-arbres, les mots qui ne sont pas des morceaux sont des chaînes ordinaires. Alors descendons la liste, extrayons les mots de chaque morceau et rejoignez-les.

>>> chunked = nltk.ne_chunk(my_sent)
>>>
>>>  [ " ".join(w for w, t in elt) for elt in chunked if isinstance(elt, nltk.Tree) ]
['WASHINGTON', 'New York', 'Loretta E. Lynch', 'Brooklyn']
3
alexis

Vous pouvez également envisager d'utiliser Spacy:

import spacy
nlp = spacy.load('en')

doc = nlp('WASHINGTON -- In the wake of a string of abuses by New York police officers in the 1990s, Loretta E. Lynch, the top federal prosecutor in Brooklyn, spoke forcefully about the pain of a broken trust that African-Americans felt and said the responsibility for repairing generations of miscommunication and mistrust fell to law enforcement.')

print([ent for ent in doc.ents])

>>> [WASHINGTON, New York, the 1990s, Loretta E. Lynch, Brooklyn, African-Americans]
1
Nic Scozzaro