Ich habe NLTKs ne_chunk
verwendet, um benannte Entitäten aus einem Text zu extrahieren:
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 ich diese Entitäten in einer Liste speichern kann? Z.B. -
print Entity_list
('WASHINGTON', 'New York', 'Loretta', 'Brooklyn', 'African')
Vielen Dank.
nltk.ne_chunk
gibt ein verschachteltes nltk.tree.Tree
-Objekt zurück, sodass Sie das Tree
-Objekt durchlaufen müssen, um zu den NEs zu gelangen.
Werfen Sie einen Blick auf Named Entity Recognition mit 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)))
... 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']
Sie können auch die Variable label
jedes Namensteils im Text extrahieren, indem Sie folgenden Code verwenden:
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))
Ausgabe:
GPE WASHINGTON
GPE New York
PERSON Loretta E. Lynch
GPE Brooklyn
Sie können sehen, dass Washington
, New York
und Brooklyn
GPE
bedeutet geopolitische Entitäten
und Loretta E. Lynch
ist eine PERSON
Da Sie als Rückgabewert eine tree
erhalten, sollten Sie die mit NE
gekennzeichneten Teilbäume auswählen.
Hier ist ein einfaches Beispiel, um alle in einer Liste zusammenzufassen:
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
Das gibt:
[Tree('NE', [('WASHINGTON', 'NNP')]), Tree('NE', [('New', 'NNP'), ('York', 'NNP')])]
oder als Liste von Listen:
[[('WASHINGTON', 'NNP')], [('New', 'NNP'), ('York', 'NNP')]]
Siehe auch: Wie navigiere ich in einem nltk.tree.Tree?
verwende tree2conlltags von nltk.chunk. Ne_chunk benötigt auch ein pos-Tagging, das Word-Token (also Word_tokenize) markiert.
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')] """
Dadurch erhalten Sie eine Liste von Tupeln: [(token, pos_tag, name_entity_tag)] Wenn diese Liste nicht genau das ist, was Sie möchten, ist es sicherlich einfacher, die gewünschte Liste aus dieser Liste zu parsen, als einen Suchtbaum.
Code und Details aus diesem Link ; Weitere Informationen finden Sie hier
Edit Ausgabe-Dokumentstring hinzugefügt
Eine Tree
ist eine Liste. Chunks sind Teilbäume, nicht-chunked-Wörter sind reguläre Zeichenfolgen. Gehen wir also die Liste durch, extrahieren Sie die Wörter aus jedem Block und fügen Sie sie hinzu.
>>> 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']
Sie können auch die Verwendung von Spacy in Betracht ziehen:
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]