Entidade de substituição com seu rótulo de entidade usando spacy
Eu quero fazer para meus dados substituindo cada entidade por seu rótulo usando o Spacy e tenho 3.000 linhas de texto necessárias para substituir entidades por sua entidade de rótulo,
por exemplo:
"A Geórgia tornou-se recentemente o primeiro estado dos EUA a" banir a cultura muçulmana ".
E quero ficar assim:
"O GPE recentemente se tornou o estado ORDINAL do GPE para" banir a cultura NORP. "
Quero que o código substitua mais do que linhas de texto.
Muito obrigado.
Por exemplo, esses códigos, mas para uma frase, eu quero modificar s (string) para coluna contém 3000 linhas
Primeiro: de ( Substitua a entidade por seu rótulo no SpaCy )
s= "His friend Nicolas J. Smith is here with Bart Simpon and Fred."
doc = nlp(s)
newString = s
for e in reversed(doc.ents): #reversed to not modify the offsets of other entities when substituting
start = e.start_char
end = start + len(e.text)
newString = newString[:start] + e.label_ + newString[end:]
print(newString)
#His friend PERSON is here with PERSON and PERSON.
Segundo: from ( mesclando tags em meu arquivo usando anotação de entidade nomeada )
import spacy
nlp = spacy.load("en_core_web_sm")
s ="Apple is looking at buying U.K. startup for $1 billion" doc = nlp(s) def replaceSubstring(s, replacement, position, length_of_replaced): s = s[:position] + replacement + s[position+length_of_replaced:] return(s) for ent in reversed(doc.ents): #print(ent.text, ent.start_char, ent.end_char, ent.label_) replacement = "<{}>{}</{}>".format(ent.label_,ent.text, ent.label_) position = ent.start_char length_of_replaced = ent.end_char - ent.start_char s = replaceSubstring(s, replacement, position, length_of_replaced) print(s) #<ORG>Apple</ORG> is looking at buying <GPE>U.K.</GPE> startup for <MONEY>$1 billion</MONEY>
Respostas
IIUC, você pode conseguir o que deseja com:
- Lendo seus textos de arquivo, cada texto em sua própria linha
- Processamento de resultados substituindo entidades, se houver, por suas tags
- Gravando resultados no disco, cada texto em sua própria linha
Demo:
import spacy
nlp = spacy.load("en_core_web_md")
#read txt file, each string on its own line
with open("./try.txt","r") as f:
texts = f.read().splitlines()
#substitute entities with their TAGS
docs = nlp.pipe(texts)
out = []
for doc in docs:
out_ = ""
for tok in doc:
text = tok.text
if tok.ent_type_:
text = tok.ent_type_
out_ += text + tok.whitespace_
out.append(out_)
# write to file
with open("./out_try.txt","w") as f:
f.write("\n".join(out))
Conteúdo do arquivo de entrada:
A Geórgia se tornou recentemente o primeiro estado dos EUA a "banir a cultura muçulmana.
Seu amigo Nicolas J. Smith está aqui com Bart Simpon e Fred. A
Apple está pensando em comprar uma startup do Reino Unido por US $ 1 bilhão
Conteúdo do arquivo de saída:
O GPE tornou-se recentemente o estado ORDINAL do GPE para "banir a cultura NORP.
Seu amigo PERSON PERSON PERSON está aqui com PERSON PERSON e PERSON.
ORG está pensando em comprar uma startup GPE para DINHEIRO
Observe o MONEYMONEY
padrão.
Isto é porque:
doc = nlp("Apple is looking at buying U.K. startup for $1 billion")
for tok in doc:
print(f"{tok.text}, {tok.ent_type_}, whitespace='{tok.whitespace_}'")
Apple, ORG, whitespace=' '
is, , whitespace=' '
looking, , whitespace=' '
at, , whitespace=' '
buying, , whitespace=' '
U.K., GPE, whitespace=' '
startup, , whitespace=' '
for, , whitespace=' '
$, MONEY, whitespace='' # <-- no whitespace between $ and 1
1, MONEY, whitespace=' '
billion, MONEY, whitespace=''