Spacy职位头衔识别异常:求Doctor替代方案及通用识别方法
问题分析与解决方案
核心问题拆解
- 逻辑顺序错误:原代码遍历预设职位时,只要第一个职位不匹配就立刻进入Spacy识别分支,没遍历完所有预设职位就提前执行后续逻辑。
- Spacy实体类型匹配偏差:
en_core_web_sm默认实体识别中,"Doctor"这类职业头衔通常不会被标记为TITLE或ORG,要么被归为PERSON,要么无法匹配到预设实体类型,导致识别失败。
修正后的代码实现
import pandas as pd import spacy from spacy.matcher import Matcher # 提前加载模型和初始化匹配器,避免重复加载拖慢性能 nlp = spacy.load("en_core_web_sm") matcher = Matcher(nlp.vocab) # 自定义职业匹配规则,覆盖常见职业场景 # 规则1:单独的职业名词(如Doctor, Engineer) pattern1 = [{"POS": "NOUN", "LOWER": {"in": ["doctor", "engineer", "teacher", "nurse", "lawyer", "accountant"]}}] # 规则2:带冠词的职业表述(如a Doctor, an Engineer) pattern2 = [{"POS": "DET"}, {"POS": "NOUN", "LOWER": {"in": ["doctor", "engineer", "teacher", "nurse", "lawyer", "accountant"]}}] matcher.add("JOB_TITLE", [pattern1, pattern2]) file_path = "insurance_data.csv" original_df = pd.read_csv(file_path) def extract_job_title(user_input): user_input = user_input.lower() preset_jobs = original_df["job_title"].unique() # 第一步:优先匹配预设职位库 for job in preset_jobs: if job.lower() in user_input: print(f"匹配到预设职位:{job}") return job # 第二步:预设库无匹配,用Spacy进行通用识别 doc = nlp(user_input) # 先使用自定义匹配器识别职业 matches = matcher(doc) if matches: _, start, end = matches[-1] job_title = doc[start:end].text.title() print(f"识别到职业:{job_title}") return job_title # 补充匹配Spacy原生实体(处理被识别为PERSON的职业) entity_jobs = [ent.text.title() for ent in doc.ents if ent.label_ in ["PERSON", "TITLE"]] if entity_jobs: print(f"识别到实体职业:{entity_jobs[-1]}") return entity_jobs[-1] # 无匹配结果 print("无法识别有效职位头衔,请重新提供。") return None # 测试示例 user_input = 'i am a Doctor' a = extract_job_title(user_input) print(a)
可扩展优化方向
- 扩充职业词库:在规则的
LOWER列表中添加更多业务场景常见的职业词汇; - 升级Spacy模型:替换为
en_core_web_md或en_core_web_lg,更大的模型实体识别准确率更高; - 训练自定义实体模型:如果有标注好的职业数据,可以训练Spacy自定义实体模型,专门识别职位头衔,进一步提升精准度。
内容的提问来源于stack exchange,提问作者Nisarg jadhav
相关产品推荐
相关产品推荐

