204 lines
4.9 KiB
Markdown
204 lines
4.9 KiB
Markdown
# 知识抽取入图前的实体对齐与发布策略
|
||
|
||
## 为什么不能直接把抽取结果写成新节点
|
||
|
||
城市知识图谱已经有高德 API 采集来的 POI 骨架数据,包括:
|
||
|
||
- `element_id / place_id`
|
||
- 名称、地址、类别、评分、开放时间
|
||
- 经纬度
|
||
- 公交站、地铁站、线路等交通节点
|
||
- 原图谱已有的 `LOCATED_IN / HAS_TAG / STOPS_AT` 等关系
|
||
|
||
百科、网页、小红书、抖音抽取出来的知识,通常是语义知识,例如:
|
||
|
||
- 历史事件
|
||
- 文化概念
|
||
- 景点组成
|
||
- 票价、面积、美誉、建议游玩时长
|
||
- 周边景点
|
||
|
||
如果直接把抽取结果写成 `ent_huaxi_park` 这种新节点,就会丢掉原 POI 的空间能力和交通关系,形成两个“花溪公园”:
|
||
|
||
```text
|
||
高德花溪公园:有经纬度、评分、交通关系
|
||
百科花溪公园:有历史、事件、概念、属性
|
||
```
|
||
|
||
这不是生产级图谱。正确做法是:**高德 POI 作为 Anchor,非结构化抽取结果作为 Evidence 和 Knowledge Patch。**
|
||
|
||
## 正确流程
|
||
|
||
```text
|
||
1. 高德/API 数据入图
|
||
-> 形成 Anchor Layer
|
||
-> Place 节点带坐标、地址、类别、评分、交通关系
|
||
|
||
2. 百度百科/网页/小红书/抖音采集
|
||
-> 保存为 Evidence
|
||
|
||
3. kg_schema_v1 抽取
|
||
-> Entity / Event / Concept / Relation / Statement / SchemaProposal
|
||
|
||
4. Entity Alignment
|
||
-> 把抽取实体和已有图谱实体做对齐
|
||
-> exact match / possible match / new candidate / conflict
|
||
|
||
5. Conflict Resolution
|
||
-> 无冲突且分数 >= 0.8:自动发布
|
||
-> 模型不一致、低分、实体歧义、字段冲突:人工审核
|
||
|
||
6. Publish
|
||
-> 把事件、概念、属性、关系挂到已有 Anchor 节点
|
||
-> 保留 evidence_quote、confidence、source
|
||
```
|
||
|
||
## Anchor 优先规则
|
||
|
||
对于城市 KG,实体主键优先级:
|
||
|
||
```text
|
||
1. 高德 element_id / place_id
|
||
2. 官方数据源 ID
|
||
3. 已有图谱 canonical id
|
||
4. LLM 抽取 temp_id
|
||
```
|
||
|
||
LLM 生成的 `temp_id` 只用于本次抽取内部引用,不能直接当作生产主键。
|
||
|
||
例如:
|
||
|
||
```text
|
||
ent_huaxi_park
|
||
-> SAME_AS
|
||
amap:B035300A51
|
||
```
|
||
|
||
正式查询应优先查:
|
||
|
||
```cypher
|
||
MATCH (p:Place {element_id:'amap:B035300A51'})-[r]->(m)
|
||
RETURN p,r,m
|
||
```
|
||
|
||
而不是只查:
|
||
|
||
```cypher
|
||
MATCH (p {id:'ent_huaxi_park'})-[r]->(m)
|
||
RETURN p,r,m
|
||
```
|
||
|
||
## 对齐结果类型
|
||
|
||
| 类型 | 含义 | 是否自动发布 |
|
||
|---|---|---|
|
||
| `SAME_AS` | 基本确定是同一实体 | 是 |
|
||
| `POSSIBLE_MATCH` | 很可能相关,但名称/类型存在歧义 | 不直接合并,进入人工或低风险关系 |
|
||
| `RELATED_TO` | 相关但不是同一实体 | 可发布关系,不合并节点 |
|
||
| `NEW_CANDIDATE` | 图谱中不存在的新实体 | 分数 >= 0.8 可候选发布 |
|
||
| `CONFLICT` | 与已有高可信字段冲突 | 人工审核 |
|
||
|
||
## 字段冲突处理
|
||
|
||
字段不能简单覆盖。按来源权重和语义含义处理:
|
||
|
||
```text
|
||
高德 open_time = 08:30-18:30
|
||
百科 opening_hours = 全天开放;收费时段8:30-18:00
|
||
```
|
||
|
||
这不是马上覆盖,而应保留为:
|
||
|
||
```text
|
||
p.open_time = 高德开放时间
|
||
p.kg_opening_hours = 百科抽取开放时间
|
||
```
|
||
|
||
同时写入 provenance:
|
||
|
||
```text
|
||
source = amap / baike
|
||
confidence
|
||
evidence_quote
|
||
updated_at
|
||
```
|
||
|
||
如果两个来源表达同一字段但明显冲突,再创建人工审核项。
|
||
|
||
## 交通关系必须来自已有图谱或空间计算
|
||
|
||
百科不会可靠提供公交/地铁网络。交通可达应来自:
|
||
|
||
```text
|
||
高德 POI 坐标
|
||
公交/地铁站点 POI
|
||
公交线路 STOPS_AT 关系
|
||
空间距离计算
|
||
路线时间 API 或缓存
|
||
```
|
||
|
||
推荐关系:
|
||
|
||
```text
|
||
(:Place)-[:NEAR_TRANSIT {distance_m, station_type}]->(:Place)
|
||
(:BusLine)-[:STOPS_AT {seq}]->(:Place)
|
||
(:Place)-[:NEARBY_ATTRACTION]->(:Place)
|
||
```
|
||
|
||
这样后续用户问:
|
||
|
||
```text
|
||
我怎么去花溪公园?
|
||
花溪公园附近有什么公交地铁?
|
||
我到青岩古镇能不能顺路去花溪公园?
|
||
```
|
||
|
||
系统能先从目的地 POI 找附近交通节点,再结合线路和路线时间回答。
|
||
|
||
## Auto Schema 在这里应该做什么
|
||
|
||
Auto Schema 不是替代已有业务脑子,也不是让模型随便改图谱。它应该做:
|
||
|
||
```text
|
||
抽取中发现新类型/关系/字段
|
||
-> 形成 Schema Proposal
|
||
-> 统计来源数量、证据数量、置信度
|
||
-> 人工或规则审核
|
||
-> 版本化升级 schema
|
||
```
|
||
|
||
例如:
|
||
|
||
```text
|
||
NEAR_TRANSIT
|
||
NEARBY_ATTRACTION
|
||
HAS_OPENING_HOURS
|
||
HAS_SCENIC_LEVEL
|
||
ManagementChangeEvent
|
||
```
|
||
|
||
这些可以进入 proposal,但事实数据不需要等待 schema 审核全部完成,稳定关系可以先以候选关系入图。
|
||
|
||
## 花溪公园当前修正结果
|
||
|
||
当前已把 `kg_schema_v1` 抽取结果对齐回高德锚点:
|
||
|
||
```text
|
||
canonical: amap:B035300A51
|
||
name: 花溪公园
|
||
lat/lng: 保留高德坐标
|
||
kg_description / kg_opening_hours / kg_scenic_level: 来自百科抽取
|
||
HAS_EVENT: 9
|
||
HAS_CONCEPT: 6
|
||
HAS_PART: 7
|
||
NEAR_TRANSIT: 7
|
||
NEARBY_ATTRACTION -> 青岩古镇: 已对齐到 amap:B035300ESE
|
||
```
|
||
|
||
对应脚本:
|
||
|
||
```text
|
||
scripts/align_huaxi_kg_with_existing_graph.py
|
||
```
|
||
|