2017-02-19 6 views
0

문자열이 있고 Person 및 Locations와 같은 일부 엔터티를 표시하려고한다고 가정 해 보겠습니다.spaCy nlp - 문자열의 태그 엔터티

string = 'My name is John Doe, and I live in USA' 
string_tagged = 'My name is [John Doe], and I live in {USA}' 

[]을 (를) 가진 사람과 {}을 (를) 표시하고 싶습니다.

내 코드 :

import spacy  
nlp = spacy.load('en') 
doc = nlp(string) 
sentence = doc.text 
for ent in doc.ents: 
    if ent.label_ == 'PERSON': 
     sentence = sentence[:ent.start_char] + sentence[ent.start_char:].replace(ent.text, '[' + ent.text + ']', 1) 
    elif ent.label_ == 'GPE': 
     sentence = sentence[:ent.start_char] + sentence[ent.start_char:].replace(ent.text, '{' + ent.text + '}', 1) 

    print(sentence[:ent.start_char] + sentence[ent.start_char:]) 

그래서 예를 들어 문자열이 잘 작동합니다. 그러나 좀 더 복잡한 문장을 사용하면 일부 엔티티 주위에서 두 번 qout을 얻습니다. 그 문장을 위해서.

string_bug = 'Canada, Canada, Canada, Canada, Canada, Canada' 

반환 >> {Canada}, {Canada}, {Canada}, {Canada}, {{Canada}}, Canada

난 단지 (높은 문자 위치로) 새로운 단어를 대체하는 것이었다 2 문장 문자열을 갈라 이유는 ... 나는 버그가 나는 루프에서 오전에있을 수 있습니다 생각 doc.ents에서 문자열의 이전 위치를 가져오고 new [] 및 {}를 사용하여 각 루프마다 문자열이 커집니다. 그러나 스파이에서 이것을 다루는 더 쉬운 방법이 있어야하는 것처럼 느껴집니다.

편집 : 반전 (doc.ents)로 해결

답변

0

여기에 내가 코드와 함께 작동 도움을 약간 수정합니다.

string = 'My name is John Doe, and I live in USA' 

import re 
import spacy 
nlp = spacy.load('en') 
doc = nlp(string) 
sentence = doc.text 
for ent in doc.ents: 
    if ent.label_ == 'PERSON': 
     sentence = re.sub(ent.text, '[' + ent.text + ']', sentence) 
    elif ent.label_ == 'GPE': 
     sentence = re.sub(ent.text, '{' + ent.text + '}', sentence) 
print sentence 

수익률 :

My name is [John Doe], and I live in {USA}