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.
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']
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
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?
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
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']
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]