2013-08-22 15 views
9

Czy jest to możliwe: uzyskać (podobną do) funkcję rozpoznawania nazwanego obiektu Stanford przy użyciu tylko NLTK?Funkcja rozpoznawania nazw (NER) Stanford z NLTK

Czy istnieje przykład?

W szczególności jestem zainteresowany wyciągnięciem LOCATION części tekstu. Na przykład z tekstu

Spotkanie odbędzie się 22 Zachodnim Westin st., South Carolina, 12345 listopada-18

idealnie chciałbym dostać coś

(S 
22/LOCATION 
(LOCATION West/LOCATION Westin/LOCATION) 
st./LOCATION 
,/, 
(South/LOCATION Carolina/LOCATION) 
,/, 
12345/LOCATION 

.....

lub po prostu

22 West Westin st., South Carolina, 12345 

Zamiast tego, jestem tylko w stanie dostać

(S 
    The/DT 
    meeting/NN 
    will/MD 
    be/VB 
    held/VBN 
    at/IN 
    22/CD 
    (LOCATION West/NNP Westin/NNP) 
    st./NNP 
    ,/, 
    (GPE South/NNP Carolina/NNP) 
    ,/, 
    12345/CD 
    on/IN 
    Nov.-18/-NONE-) 

pamiętać, że jeśli wejdę mój tekst do http://nlp.stanford.edu:8080/ner/process dostaję wyniki dalekie od doskonałości (ulica i numer domu Kod pocztowy nadal brakuje), ale przynajmniej „ST. " jest częścią LOCATION, a South Carolina to LOKALIZACJA, a nie jakaś "GPE/NNP":?

Co robię źle, proszę? jak mogę to naprawić, aby użyć NLTK do ekstrakcji fragmentu lokalizacji z jakiegoś tekstu?

Wielkie dzięki z góry!

Odpowiedz

19

nltk DOES mają interfejs dla Stanford NER, sprawdź nltk.tag.stanford.NERTagger.

from nltk.tag.stanford import NERTagger 
st = NERTagger('/usr/share/stanford-ner/classifiers/all.3class.distsim.crf.ser.gz', 
       '/usr/share/stanford-ner/stanford-ner.jar') 
st.tag('Rami Eid is studying at Stony Brook University in NY'.split()) 

wyjściowa:

[('Rami', 'PERSON'), ('Eid', 'PERSON'), ('is', 'O'), ('studying', 'O'), 
('at', 'O'), ('Stony', 'ORGANIZATION'), ('Brook', 'ORGANIZATION'), 
('University', 'ORGANIZATION'), ('in', 'O'), ('NY', 'LOCATION')] 

Jednak za każdym razem dzwonić tag, NLTK prostu pisze zdanie docelową do pliku i uruchamia narzędzie wiersza poleceń Stanford NER analizować ten plik i wreszcie przetwarza dane wyjściowe z powrotem do pyton. Dlatego też obciążenie klasyfikatorów ładunkowych (około 1 min za każdym razem) jest nieuniknione.

Jeśli to jest problem, użyj Pyner.

Pierwsze uruchomienie Stanford NER jako serwer

java -mx1000m -cp stanford-ner.jar edu.stanford.nlp.ie.NERServer \ 
-loadClassifier classifiers/english.all.3class.distsim.crf.ser.gz -port 9191 

następnie przejdź do folderu pyner

import ner 
tagger = ner.SocketNER(host='localhost', port=9191) 
tagger.get_entities("University of California is located in California, United States") 
# {'LOCATION': ['California', 'United States'], 
# 'ORGANIZATION': ['University of California']} 
tagger.json_entities("Alice went to the Museum of Natural History.") 
#'{"ORGANIZATION": ["Museum of Natural History"], "PERSON": ["Alice"]}' 

nadzieję, że to pomaga.

+1

Czy wiesz, czy mogę wyszkolić Stanford NER i jak? Próbowałem tego. "Czarnoksiężnik z krainy Oz opuszcza Szmaragdowe Miasto". a "Aleksander Wielki podbił Imperium Perskie". Żaden nie zadziałał. – Hans

+0

@edfward java uruchamia go na porcie 9191, ale python uruchamia go na porcie 8080. Dlaczego tak jest? – bernie2436

+0

@ akh2103 moja wina. Poprawiłem w odpowiedzi, powinny one być spójne, podczas gdy rzeczywisty port może się różnić. – junjiah