关系抽取配置怎么配?从schema定义到批量入库的实操流程

关系抽取配置通常分四步走:先定义实体和关系类型(schema),再准备少量标注样例,然后选择规则或模型方式配置抽取器,最后批量运行并抽样检查结果。
下面以 Python 环境下的开源工具为例,说明每一步的具体操作和容易出错的点。

先定 schema,再选工具

关系抽取不是打开一个开关就能用,配置前必须明确你要抽什么。
schema 就是实体类型和关系类型的清单,例如:

  • 实体类型:人物、公司、职位
  • 关系类型:任职于、创始人、总部位于

schema 越具体,后续配置越容易。
建议先用表格列出「头实体类型-关系-尾实体类型」,例如 人物-任职于-公司。

工具选择上,如果文本格式固定、关系类型少,优先用规则或词典匹配,成本低且可控;
如果表达多样,再考虑预训练模型。
本文演示用 spaCy 的规则匹配和 pipeline 组件做基础配置,不依赖 GPU。

安装依赖:

pip install spacy
python -m spacy download zh_core_web_sm

zh_core_web_sm 是中文小模型,适合做分词和基础实体识别。
如果下载慢,可以换用镜像源或手动下载模型包。

准备标注样例和词典

规则配置需要词典,模型配置需要标注样例。
两种方式都建议先准备 20~50 条覆盖主要关系的句子。

以「人物-任职于-公司」为例,准备一个词典文件 patterns.jsonl,每行一个模式:

{"label": "EMPLOYED_BY", "pattern": [{"LOWER": "在"}, {"ENT_TYPE": "ORG"}, {"LOWER": "工作"}]}

这个模式表示「在 + 组织机构 + 工作」的短语结构。
实际配置时,ENT_TYPE 需要和 spaCy 识别出的实体类型对齐,中文模型的组织机构类型通常是 ORG。

如果使用模型方式,需要把句子转成标注格式,例如:

{"text": "张三在阿里巴巴工作", "entities": [[0, 2, "PERSON"], [3, 7, "ORG"]], "relations": [[0, 2, 3, 7, "EMPLOYED_BY"]]}

标注时注意实体边界要精确到字符索引,关系头尾实体必须出现在 entities 列表中。

配置抽取器并跑通单条文本

规则方式在 spaCy 中通过 EntityRuler 和自定义组件实现。
下面是一个最小可运行脚本 relation_extract.py:

import spacy
from spacy.matcher import Matcher

nlp = spacy.load("zh_core_web_sm")
matcher = Matcher(nlp.vocab)

# 匹配「在 + ORG + 工作」结构
pattern = [{"LOWER": "在"}, {"ENT_TYPE": "ORG"}, {"LOWER": "工作"}]
matcher.add("EMPLOYED_BY", [pattern])

def extract_relations(doc):
    matches = matcher(doc)
    results = []
    for match_id, start, end in matches:
        span = doc[start:end]
        org = [ent for ent in span.ents if ent.label_ == "ORG"]
        if org:
            results.append({"relation": "EMPLOYED_BY", "org": org[0].text})
    return results

text = "张三在阿里巴巴工作"
doc = nlp(text)
print(extract_relations(doc))

运行 python relation_extract.py,预期输出类似 [{'relation': 'EMPLOYED_BY', 'org': '阿里巴巴'}]。
如果输出为空,先用 print([(ent.text, ent.label_) for ent in doc.ents]) 检查实体识别是否正常。

模型方式则使用 spacy train 命令加载配置文件和标注数据,配置文件中需要设置 [components.relation_extractor] 的 model 和 labels。
训练命令示例:

python -m spacy train config.cfg --output ./output --paths.train ./train.spacy --paths.dev ./dev.spacy

训练前需要把标注 JSON 转成 spaCy 的二进制格式,具体转换命令参考官方文档,不要直接复用不兼容的旧版命令。

批量处理与结果验证

单条跑通后,把输入文本整理成每行一条的 input.txt,用循环批量处理:

with open("input.txt", encoding="utf-8") as f:
    for line in f:
        doc = nlp(line.strip())
        print(extract_relations(doc))

验证阶段重点看三件事:

  • 召回率:抽样 30 条结果,统计漏抽的比例。漏抽多说明模式覆盖不够,需要补充词典或增加标注样例。
  • 准确率:统计抽错的比例。错抽多通常是实体边界识别不准,检查分词和实体类型。
  • 关系方向:头实体和尾实体是否颠倒,规则模式中顺序要固定。

如果批量处理时出现内存增长,把 nlp 对象放在循环外复用,不要每条文本重新加载模型。

容易踩的坑

第一,实体类型不匹配。
中文小模型对机构名识别不稳定,配置前先用测试句确认 ORG 能识别出目标公司名,否则规则永远匹配不上。

第二,标注索引偏移。
手动写字符索引容易多算空格,建议用标注工具导出,不要手写。

第三,关系类型膨胀。
一开始就定义十几种关系,标注和验证都做不完。
先跑通 2~3 个核心关系,再逐步扩展。

第四,忽略负样本。
只准备正例会导致模型把无关句子也抽出关系,标注时保留一部分不包含目标关系的句子。

常见疑问

规则和模型能混用吗?
可以。
常见做法是先用规则覆盖高频固定表达,再用模型处理长尾句子,最后合并结果去重。

需要多少标注数据?
规则方式 20 条左右即可起步;
模型方式通常需要几百条以上,具体取决于关系类型数量和句子多样性,建议先用小样本训练看验证集表现再决定是否扩充。

中文关系抽取必须用大模型吗?
不一定。
文本结构固定、关系类型少时,词典加规则就能满足需求,成本更低且结果可解释。

配置完成后如何持续维护?
把每次抽错的句子加入测试集,定期重跑验证,规则和模型都按版本管理,不要直接改生产配置。

分享到:
上一篇
从三元组到可查询图谱:手写知识图谱构建的最小步骤
下一篇
用 CSV 导入 Neo4j 知识图谱并验证查询结果
1
系统公告

关于香港云优质服务器IP地址更换的通知

尊敬的客户: 因原IP运营商大幅涨价,为避免成本转嫁至用户,我司决定更换IP服务商。本次更换后,您的续费价格将保持不变,且新IP网络质量与服务标准不受影响。新IP已分配至后台,即刻生效(更换的新IP都是香港原生IPv4)。 涉及 IP 段: 45.192.x.x 旧 IP 停用时间: 2026 年 12 月 1 日
服务中心
客服
在线客服
24小时为您服务
咨询
联系我们
联系我们,为您的业务提供专属服务。
24/7 技术支持
如果您遇到寻求进一步的帮助,请过工单与我们进行联系。
24/7 即时支持
泽御云
售前客服
泽御云
泽御云
售后客服
泽御云
技术支持
评价
您对当前页面的整体感受是否满意?
😞
非常不满意
😕
不满意
😐
一般
🙂
满意
😊
非常满意