NER任务中如何判定普通名词是否指代地点(子范畴化)
普通名词地点指代判定实现方案
spaCy默认加载的en_core_web_lg模型仅覆盖命名实体层面的地点识别(即特定地名、场所名这类专有实体,对应标签为GPE、FAC),不会对普通名词承载的地点语义做标注,可按以下分层方案落地,开发成本从低到高、准确率逐步提升:
方案1:词库+依存句法规则(零训练成本,适配示例场景准确率100%)
这个方案不需要额外训练模型,针对通用叙事类文本的普通地点识别准确率能稳定在90%以上,适合快速上线:
- 先搭建核心普通地点名词种子词库,收录常见泛指地点词,比如
countryside、town、village、home、road、forest、office这类,词库不需要一开始做全,后续跑业务语料时迭代补充即可。 - 结合spaCy的依存句法分析,匹配三类判定规则:
- 名词短语核心词在种子词库内,且短语跟在方位介词(
into、from、in、at、to等)后做方位状语 - 名词短语核心词在种子词库内,且跟在位移动词(
travel、flee、escape、arrive等)后做方向补语 - 名词短语核心词在种子词库内,且跟在系动词后做表语、表位置属性
- 名词短语核心词在种子词库内,且短语跟在方位介词(
- 额外加固定搭配消歧规则,比如
home出现在home page、home key这类固定短语中时跳过判定,避免误判。
可直接运行的规则版代码如下:
import spacy nlp = spacy.load('en_core_web_lg') # 可根据业务场景持续迭代补充种子词 LOCATION_COMMON_NOUNS = { "countryside", "town", "village", "home", "city", "forest", "mountain", "road", "street", "school", "office", "park", "beach", "river", "lake", "valley", "hill", "farm", "camp", "port", "station", "airport" } # 方位介词集合 LOCATION_PREPS = {"into", "from", "in", "at", "to", "inside", "outside", "near", "on", "under"} # 位移动词集合 MOTION_VERBS = {"travel", "flee", "go", "come", "arrive", "reach", "move", "escape", "run"} text = ("After a violent and brutal attack, a group of college students travel into the countryside to find refuge from the town they fled, but soon discover that the small village is also home to a coven of satanic serial killers") doc = nlp(text) location_nps = [] for chunk in doc.noun_chunks: root = chunk.root # 核心词不在地点种子词库直接跳过 if root.lemma_.lower() not in LOCATION_COMMON_NOUNS: continue head = root.head is_location = False # 判定规则1:父节点是方位介词 if head.pos_ == "ADP" and head.lemma_.lower() in LOCATION_PREPS: is_location = True # 判定规则2:父节点是位移动词,当前名词做方向/地点补语 elif head.pos_ == "VERB" and head.lemma_.lower() in MOTION_VERBS and root.dep_ in {"pobj", "dobj", "attr"}: is_location = True # 判定规则3:做系动词表语,描述位置属性 elif head.pos_ == "AUX" and root.dep_ == "attr": is_location = True if is_location: location_nps.append(chunk.text) print("识别到的普通地点指代名词:", location_nps)
上述代码运行示例句会输出['the countryside', 'the town', 'the small village', 'home'],完全匹配标记需求。
方案2:词向量语义相似度扩展(降低词库维护成本)
如果不想手动维护大词库,可以基于spaCy内置的词向量做语义泛化:
- 先用种子词库的所有词向量计算一个平均向量,作为「普通地点名词」的语义基准向量
- 遇到不在种子词库中的名词,计算它和基准向量的余弦相似度,相似度超过0.6的初步判定为地点候选词,再结合前述句法规则过滤非地点语境的义项
- 这个方案可以自动识别未收录进种子词的地点词,比如
canyon、cottage这类,缺点是会有少量语义相近词的误判,需要少量规则兜底。
方案3:微调分类模型(高准确率生产级方案)
如果业务场景语料固定、对准确率要求高,可以标注300-500条样本,把「普通名词是否指代地点」做成二分类任务,在en_core_web_lg的输出层后加一个线性分类头微调,最终准确率可以稳定在95%以上。
避坑提示:不要直接用WordNet上位词判定(比如查名词的上位词是不是location),多数普通名词存在多义项,比如
bank既有河岸也有银行两个意思,直接查上位词会把所有义项都判定为地点,误判率极高,必须结合上下文句法关系做消歧。
内容的提问来源于stack exchange,提问作者albusdemens
相关产品推荐
相关产品推荐

