4. 知识抽取技术:实体识别、关系抽取、属性抽取
知识抽取这个环节,说白了就是给原始文本做手术。
你要从一堆密密麻麻的文字里,把实体、关系、属性一个个精准地切出来。
我个人认为,这是整个知识图谱搭建中最“吃经验”的一步。
模型选得不对,或者标注质量不行,后面所有的规则推导都会跟着跑偏。
我早期接手过一个质量规则项目,就是实体识别没做好,结果把“焊接温度”和“预热温度”当成了同一个实体——整批规则全废。那之后我格外重视这三大基础能力。
4.1 实体识别:找到图谱里的“节点”
实体识别,也叫命名实体识别,英文简称 NER。
它的任务很简单:从文本中定位出有特定意义的词,比如产品名、工艺名、缺陷名、参数名。
举个质检场景的例子:
输入:Q235钢材在焊接后出现气孔缺陷,焊接电流设定为180A。
输出:
- [Q235钢材](材料实体)
- [气孔](缺陷实体)
- [焊接电流](参数实体)
- [180A](值实体)
为什么会这么分?
因为知识图谱里,每个实体都是一个独立的节点。你如果漏了“气孔”这个缺陷实体,后续的质量规则就永远查不到它。
常用的实体识别策略
我个人习惯把方法分三类:
| 方法 | 适用场景 | 典型工具 |
|---|---|---|
| 词典/规则匹配 | 术语固定、变体少 | 正则、Aho-Corasick |
| 统计机器学习 | 语料规模中等 | CRF、HMM |
| 深度学习 | 语料大、变体多 | BERT、BiLSTM-CRF |
一条实在的经验:
在工业质量领域,很多术语是固定的,比如“GB/T 3091-2015”。这种情况下,我会先用词典匹配兜住高精度命中,再用模型做泛化召回。两不耽误。
我个人很少上来就上大模型。
你想想看,如果你们车间的SOP里,焊接参数永远是固定写法,那正则可能比BERT跑得还快。
避坑:实体重叠
我曾经遇到一个案例:“不锈钢管焊接裂纹”。这里的实体既可以是“不锈钢管”(材料),也可以是“焊接裂纹”(缺陷)。两个实体叠在一起,传统 BIO 标注很容易漏标。
建议用嵌套实体标注方案,或者分层解码。别偷懒。
4.2 关系抽取:连接实体的“边”
实体找出来了,接下来要问:它们之间是什么关系?
关系抽取,就是给图谱加“边”。
举个例子:
文本:Q235钢材的屈服强度为235MPa。
关系抽取结果:
- 三元组:(Q235钢材, 属性值, 屈服强度)
- 三元组:(屈服强度, 具体数值, 235MPa)
在质量规则场景里,关系大致分几类:
- 属性关系:材料 → 参数(“Q235” → “屈服强度”)
- 约束关系:参数 → 阈值(“屈服强度” → “≥235MPa”)
- 因果/条件关系:工艺 → 缺陷控制(“焊后热处理” → “减少裂纹”)
我在项目中遇到过很多次,关系抽取的准确率直接决定了规则引擎的查询质量。
比如你抽出了“材料:Q235”,但没抽出“关系:要求屈服强度≥235MPa”,那规则根本触发不了。
业界主流做法
| 方式 | 优点 | 缺点 |
|---|---|---|
| Pipeline(流水线) | 实现简单、可独立优化 | 误差传播,实体错则关系错 |
| 联合抽取(Joint) | 整体F1更高 | 模型复杂,训练资源大 |
一个小建议:
如果你的语料里关系类型少于10种,用Pipeline就行,够用了。我自己的经验是,关系15种以上,联合抽取才值得上。
4.3 属性抽取:填实体的“细节卡片”
属性抽取,就是给每个实体装上一张“信息卡”。
比如“焊接电流”这个参数实体,它有哪些属性?数值范围、单位、适用材料、引用标准……
属性抽取通常有两种思路:
- 基于模式:写正则或者模板。适合格式固定的描述。
- 基于模型:用序列标注或阅读理解模型。适合自由文本。
我举个例子:
文本:焊接电流应控制在180A-220A之间,超出范围易产生未熔合缺陷。
属性抽取目标:
- 实体:焊接电流
- 属性-最小值:180A
- 属性-最大值:220A
- 属性-关联缺陷:未熔合
注意看,这里“未熔合”本身也是一个实体——它跟“焊接电流”产生了条件关系。
所以属性抽取做完之后,往往还要跟关系抽取联动。
4.4 三者的协同工作流
实际上,实体识别、关系抽取、属性抽取不是三个独立任务。
我自己团队里的落地流程是这样:
- 先用实体识别把名词性实体都挖出来。
- 然后做属性抽取,给实体贴“值标签”。
- 最后做关系抽取,确定实体之间怎么连接。
这样一来,每步输出的数据量是递减的,后续处理压力也小。
你想想看,如果你先做关系抽取,结果实体都没找全,那关系肯定乱七八糟。
我画了一张图,把这个三层递进关系说明白:
小结一下:
知识抽取不是一次性工作。它的质量直接影响后续的规则推导。我一般会先把实体识别做到95%以上准确率,再动关系抽取。属性抽取则是贯穿始终的细活——很多规则失败,就是因为属性值没抽全。