使用spacy从文档中删除命名实体

8

我试图从一个文件中删除被spacy认为是命名实体的单词,基本上将字符串示例中的"Sweden"和"Nokia"移除。但是我无法解决实体被存储为span的问题。所以当将它们与spacy doc的单个标记进行比较时,会提示错误。

在后续步骤中,此过程应该是应用于存储在pandas数据帧中的多个文本文件的函数。

我希望能得到任何形式的帮助和建议,以便更好地发布问题,因为这是我在这里发布的第一个问题。


nlp = spacy.load('en')

text_data = u'This is a text document that speaks about entities like Sweden and Nokia'

document = nlp(text_data)

text_no_namedentities = []

for word in document:
    if word not in document.ents:
        text_no_namedentities.append(word)

return " ".join(text_no_namedentities)


它会产生以下错误:

类型错误:参数“other”的类型不正确(期望是spacy.tokens.token.Token,实际得到的是spacy.tokens.span.Span)


你想对命名实体做什么?只是从字符串中删除它们并返回没有它们的字符串吗? - APhillips
是的,那就是目标。 - john_28
@john_28 你知道如果我有代码行应该怎么办吗? - user12904074
4个回答

3

这将无法处理跨多个标记的实体。

import spacy
nlp = spacy.load('en_core_web_sm')
text_data = 'New York is in USA'
document = nlp(text_data)

text_no_namedentities = []
ents = [e.text for e in document.ents]
for item in document:
    if item.text in ents:
        pass
    else:
        text_no_namedentities.append(item.text)
print(" ".join(text_no_namedentities))

输出

'纽约在'

这里正确移除了USA,但无法消除New York

解决方法

import spacy
nlp = spacy.load('en_core_web_sm')
text_data = 'New York is in USA'
document = nlp(text_data)
print(" ".join([ent.text for ent in document if not ent.ent_type_]))

输出

'在...中'


2
这将为您提供所需的结果。查看命名实体识别可以帮助您进行下一步操作。
import spacy

nlp = spacy.load('en_core_web_sm')

text_data = 'This is a text document that speaks about entities like Sweden and Nokia'

document = nlp(text_data)

text_no_namedentities = []

ents = [e.text for e in document.ents]
for item in document:
    if item.text in ents:
        pass
    else:
        text_no_namedentities.append(item.text)
print(" ".join(text_no_namedentities))

输出:

This is a text document that speaks about entities like and

这个答案在像“纽约”这样的实体情况下是不适用的,正如@kochar96所提到的。 - undefined

1
你可以使用实体属性start_char和end_char来将实体替换为空字符串。
import spacy
nlp = spacy.load('en_core_web_sm')
text_data = 'New York is in USA'
document = nlp(text_data)

text_no_namedentities = []
ents = [(e.start_char,e.end_char)  for e in document.ents]

for ent in ents:
    start_char, end_char = ent
    text_data = text_data[:start_char] + text_data[end_char:]  
print(text_data)

0

我遇到了一些问题,kochar96和APhillips的解决方案修改了文本,由于spacy的分词,所以无法在连接后将--> ca n't还原为can't。

我无法完全理解Batmobil的解决方案,但是按照使用起始和结束索引的一般思路进行了操作。

在打印输出中解释了numpy解决方案的hack-y方法。(没有时间做更合理的事情,随时可以编辑和改进)

text_data = "This can't be a text document that speaks about entities like Sweden and Nokia"
my_ents = [(e.start_char,e.end_char) for e in nlp(text_data).ents]
my_str = text_data

print(f'{my_ents=}')
idx_keep = [0] + np.array(my_ents).ravel().tolist() + [-1]
idx_keep = np.array(idx_keep).reshape(-1,2)
print(idx_keep)

keep_text = ''
for start_char, end_char in idx_keep:
    keep_text += my_str[start_char:end_char]
print(keep_text)

my_ents=[(62, 68), (73, 78)]
[[ 0 62]
 [68 73]
 [78 -1]]
This can't be a text document that speaks about entities like  and 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接