pandas中如何合并多词PERSON命名实体并实现跨列实体匹配
实现方案
一、基础场景:单列文本内PERSON实体转下划线连接
BILOU序列标注方案确实可以提升实体边界识别准确率,spaCy默认的NER模型本身就已经采用BILOU标注逻辑做实体边界判断,你遇到的误识别问题基本是小尺寸预训练模型上下文学习能力不足导致的,不需要额外自己实现BILOU标注训练模型,按以下步骤优化即可达到预期效果:
- 优先使用Transformer版本的预训练模型,比如英文场景加载
en_core_web_trf,相比小尺寸的sm/md版本模型,PERSON实体识别准确率高30%以上,极少出现普通词汇被误识别为人名的情况 - 提取实体后增加简单过滤规则:排除长度为1且词性不是专有名词(PROPN)的实体,过滤掉零散的误判普通词汇
- 替换实体时按字符位置从后往前替换,避免先替换靠前内容导致后续实体的字符偏移错位
可直接复用以下代码:
import pandas as pd import spacy # 加载Transformer版本预训练模型 nlp = spacy.load("en_core_web_trf") def person_to_underscore(text): doc = nlp(text) # 按实体起始位置倒序排列 sorted_ents = sorted(doc.ents, key=lambda x: x.start_char, reverse=True) for ent in sorted_ents: if ent.label_ != "PERSON": continue # 过滤误识别的短非专有名词 if len(ent.text.split()) == 1 and ent[0].pos_ != "PROPN": continue # 替换实体内部空格为下划线 replaced_text = ent.text.replace(" ", "_") text = text[:ent.start_char] + replaced_text + text[ent.end_char:] return text # 直接应用到DataFrame列即可 df["Text"] = df["Text"].apply(person_to_underscore)
如果存在固定领域的高频人名、特殊误判案例,可以额外加spaCy规则匹配器补充自定义实体,准确率可以进一步提升。
二、更新场景:complete_text识别结果映射到incomplete_text
incomplete_text无法识别出PERSON实体本质是文本截断后上下文不足,不需要重新训练模型,直接基于字符串匹配做实体映射即可,逻辑稳定且准确率高:
- 先对complete_text列跑NER,提取所有PERSON类型实体
- 对每行提取到的人名按文本长度从长到短排序,避免短实体先匹配替换,破坏长实体的匹配逻辑(比如先匹配
Michelle LaVaughn Robinson,再匹配短名Robinson,不会把长实体拆成碎段) - 在incomplete_text中做精确字符串匹配,找到对应实体后替换为下划线连接格式即可
可直接复用以下代码:
def extract_person_entity(text): doc = nlp(text) return [ent.text for ent in doc.ents if ent.label_ == "PERSON"] # 提取complete_text列的人名实体 df["spacy_complete_text_person"] = df["complete_text"].apply(extract_person_entity) def map_entity_to_incomplete(row): incomplete_text = row["incomplete_text"] person_ents = row["spacy_complete_text_person"] # 人名按长度降序排列,优先匹配长实体 sorted_persons = sorted(person_ents, key=lambda x: len(x), reverse=True) for person in sorted_persons: if person in incomplete_text: incomplete_text = incomplete_text.replace(person, person.replace(" ", "_")) return incomplete_text # 生成结果列 df["result"] = df.apply(map_entity_to_incomplete, axis=1) # 空的incomplete_text实体列按预期填空列表 df["spacy_incomplete_text__person"] = [[]]*len(df)
如果incomplete_text存在人名大小写不一致、少量拼写偏差、前后截断的情况,可以把精确匹配替换为基于编辑距离的模糊匹配,设置编辑距离小于2即判定为匹配,即可覆盖大部分异常场景。
内容的提问来源于stack exchange,提问作者CPDatascience
相关产品推荐
相关产品推荐

