使用Spacy NER识别PERSON实体合并多词人名及代码报错修复
代码错误排查
原代码存在以下几个问题,直接导致运行报错、无法实现预期效果:
- 循环语法非法:写
for token.text in doc时没有正确声明迭代变量,是触发name 'token' is not defined报错的直接原因 - 实体调用逻辑错误:spaCy的识别结果中,命名实体统一存储在
doc.ents属性下,不需要遍历token逐个判断;且实体标签需要通过ent.label_属性获取,PERSON类实体的标签值为全大写的"PERSON",不是代码里写的"Person" - 变量名不统一:函数入参命名为
string,后续字符串替换操作却调用了未定义的txt变量 - 性能缺陷:将spacy模型加载逻辑写在apply调用的函数内部,会导致每处理一行数据就重新加载一次百MB级的模型,运行效率极低
- 替换逻辑漏洞:如果从字符串头部往尾部顺序替换,前面的替换操作会改变字符串长度,导致后续实体的字符索引错位,出现替换错误
修正后可运行代码
首先确保已经安装对应的spacy模型,终端执行以下命令即可:
python -m spacy download en_core_web_trf
功能实现代码:
import spacy import pandas as pd # 模型全局仅加载一次,避免重复加载消耗资源 nlp = spacy.load("en_core_web_trf") def merge_person_name(text: str) -> str: doc = nlp(text) # 提取所有PERSON类型实体,按实体在文本中的起始位置倒序排列 # 倒序替换不会改变前面未处理部分的字符索引,避免错位 person_entities = sorted( [ent for ent in doc.ents if ent.label_ == "PERSON"], key=lambda x: x.start_char, reverse=True ) for ent in person_entities: s_pos = ent.start_char e_pos = ent.end_char # 将实体内部的空格替换为下划线 origin_ent_text = text[s_pos:e_pos] text = text[:s_pos] + origin_ent_text.replace(" ", "_") + text[e_pos:] return text # 批量处理数据集text列 df["text"] = df["text"].apply(merge_person_name)
运行效果
使用提供的测试数据集运行后,输出结果完全符合预期:
text 0 use your superpowers 1 vote for Barack_Obama 2 vote for Marine_Le_Pen 3 play with Michael_Jordan 4 support the supporters
内容的提问来源于stack exchange,提问作者CPDatascience
相关产品推荐
相关产品推荐

