2015-08-05 3 views
8

habe ich NLTK ne_chunk der aus einem Text benannten Entitäten zu extrahieren:NLTK Named Entity Anerkennung auf eine Python-Liste

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) 

Aber ich kann nicht herausfinden, wie diese Entitäten zu einer Liste speichern? Z.B. -

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

Danke.

+0

Was 'ne_chunk tut()' Rückkehr statt? Was genau stecken Sie fest? – lenz

+0

mögliches Duplikat von [Named Entity Recognition mit regulärem Ausdruck: NLTK] (http://stackoverflow.com/questions/24398536/named-entity-recognition-withregular-expression-nltk) – alvas

+0

Wenn ich Ihren Code ausführen, bekomme ich ein Indexfehler – MERose

Antwort

18

nltk.ne_chunk gibt ein verschachteltes nltk.tree.Tree Objekt, so dass Sie das Tree Objekt überqueren müßten die NEs zu bekommen.

Werfen Sie einen Blick auf Named Entity Recognition with Regular Expression: 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))) 
...  prev = None 
...  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'] 
4

Wie Sie einen tree als Rückgabewert bekommen, ich denke, man diese Teilbäume auswählen möchten, die hier mit NE

markiert sind, ist ein einfaches Beispiel alle, die in einer Liste zu sammeln:

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 

Dies gibt:

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

oder als Liste von Listen:

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

Siehe auch: How to navigate a nltk.tree.Tree?

2

A Tree eine Liste ist. Chunks sind Teilbäume, nicht-chunked Wörter sind reguläre Strings. Gehen wir also die Liste durch, extrahieren Sie die Wörter aus jedem Block und schließen Sie sich ihnen an.

>>> 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'] 
2

Sie auch die label jedes Namens Entity im Text mit diesem Code extrahieren:

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)) 

Ausgang:

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

Sie können sehen, Washington, New York und Brooklyn sind GPE bedeutet geo-politischen Einheiten

und Loretta E. Lynch ist ein PERSON

0

Verwendung tree2conlltags von nltk.chunk. Auch ne_chunk benötigt eine Pos-Markierung, die Word-Token markiert (benötigt also 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')] """ 

Dies wird Ihnen eine Liste von Tupeln geben: [(Token, pos_tag, name_entity_tag)] Wenn diese Liste ist nicht genau das, was Sie wollen, ist es sicherlich einfacher, die Liste, die Sie aus dieser Liste wollen analysieren dann ein Nltk-Baum.

Code und Details von this link; überprüfen Sie es für weitere Informationen

bearbeiten addierte Ausgabe docstring