知识图谱构建与应用

知识图谱从概念到落地:RDF vs 属性图模型、实体抽取与关系识别、图嵌入与知识推理、大语言模型结合 KG 的检索增强技术。

导语:连接碎片知识为结构化智慧

当今互联网的信息汪洋中,最大的矛盾是:信息过量而知识稀缺。知识图谱(Knowledge Graph, KG)试图解决这个问题——它不是简单存储数据,而是将碎片化的信息连接为结构化的知识网络。

Google Knowledge Graph(2012)是这个词最著名的来源,但知识图谱的理念可以追溯到语义网(Semantic Web)时代。今天,KG 的应用已远超搜索引擎:推荐系统、智能客服、药物研发、金融风控,大语言模型的幻觉问题也需要借助知识图谱来缓解。

一句话总结:知识图谱的核心价值是"连接碎片"——将分散在文档、数据库、API 中的实体和关系结构化,形成可查询、可推理的知识网络。


1. 知识图谱的数据模型

1.1 RDF 三元组模型

RDF(Resource Description Framework)是 W3C 定义的知识表示标准,以**三元组(Subject-Predicate-Object)**为基本单位:

@prefix ex: <http://example.org/> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .

ex:Einstein rdf:type ex:Scientist ;
            foaf:name "Albert Einstein" ;
            ex:birthPlace ex:Germany ;
            ex:developed ex:TheoryOfRelativity .

ex:TheoryOfRelativity rdf:type ex:ScientificTheory ;
                      ex:published "1905" .

三元组的表达能力:

(Albert Einstein, developed, Theory of Relativity)
(Theory of Relativity, influences, Astrophysics)
(Einstein, birthPlace, Germany)
(Germany, capital, Berlin)

1.2 RDF vs 属性图

维度RDF属性图(Neo4j)
基础单元三元组 (S-P-O)节点 + 关系 + 属性
URI 系统所有实体和关系都有全局 URI通常使用本地标签
属性需要额外的三元组表示直接附加在节点/关系上
查询语言SPARQLCypher
推理能力RDF Schema / OWL 本体推理无内置推理,依赖外部逻辑
生态系统语义网、Linked Data企业应用、社交网络
存储系统Jena, Virtuoso, GraphDBNeo4j

1.3 SPARQL 查询示例

# 查询爱因斯坦的所有理论
SELECT ?theory ?name
WHERE {
  ?einstein foaf:name "Albert Einstein" .
  ?einstein ex:developed ?theory .
  ?theory foaf:name ?name .
}

# 查询出生在德国的科学家的理论
SELECT ?scientist ?theory
WHERE {
  ?scientist rdf:type ex:Scientist ;
             ex:birthPlace ex:Germany ;
             ex:developed ?theory .
}

# 两跳推理:德国科学家的理论影响了哪些领域
SELECT DISTINCT ?field
WHERE {
  ?scientist ex:birthPlace ex:Germany ;
             ex:developed ?theory .
  ?theory ex:influences ?field .
}

一句话总结:RDF 强调语义互操作性(全球 URI、本体推理),属性图强调查询性能和开发效率——学术和标准领域倾向 RDF,企业应用倾向属性图。


2. 知识图谱构建流程

2.1 构建流水线

原始数据(文档/数据库/API)
       │
       ▼
┌──────────────┐
│ 数据预处理     │  ← 清洗、分词、标准化
└──────────────┘
       │
       ▼
┌──────────────┐
│ 实体抽取(NER)│  ← 识别人名、地名、组织、时间
└──────────────┘
       │
       ▼
┌──────────────┐
│ 关系抽取       │  ← X 是 Y 的创始人,X 开发了 Y
└──────────────┘
       │
       ▼
┌──────────────┐
│ 实体对齐/链接  │  ← "爱因斯坦" → http://dbpedia.org/resource/Albert_Einstein
└──────────────┘
       │
       ▼
┌──────────────┐
│ 知识推理与补全 │  ← 基于规则的推理、链路预测
└──────────────┘
       │
       ▼
┌──────────────┐
│ 质量评估       │  ← 一致性、完整性、准确性检查
└──────────────┘
       │
       ▼
知识图谱存储

2.2 实体抽取(Named Entity Recognition)

# 使用 spaCy 进行 NER
import spacy

nlp = spacy.load("zh_core_web_trf")  # 中文 transformer 模型

text = "爱因斯坦出生于德国,后来开发了相对论,对美国物理学产生了重要影响。"
doc = nlp(text)

for ent in doc.ents:
    print(f"{ent.text} -> {ent.label_}")

# 输出:
# 爱因斯坦 -> PERSON
# 德国 -> GPE
# 相对论 -> WORK_OF_ART
# 美国 -> GPE

2.3 关系抽取

基于规则的方法(简单但精确度高):

import re

# 基于模板的关系抽取
def extract_relations(text, entities):
    relations = []
    
    # 模板:X 出生于 Y
    pattern = r"(.+?)出生于(.+?)[,。]"
    for match in re.finditer(pattern, text):
        subj = match.group(1).strip()
        obj = match.group(2).strip()
        if subj in entities and obj in entities:
            relations.append((subj, "birthPlace", obj))
    
    # 模板:X 开发了 Y
    pattern = r"(.+?)开发了(.+?)[,。]"
    for match in re.finditer(pattern, text):
        subj = match.group(1).strip()
        obj = match.group(2).strip()
        if subj in entities and obj in entities:
            relations.append((subj, "developed", obj))
    
    return relations

基于深度学习的方法(更通用但需要标注数据):

# BERT  fine-tuning 进行关系分类
from transformers import BertTokenizer, BertForSequenceClassification
import torch

tokenizer = BertTokenizer.from_pretrained("bert-base-chinese")
model = BertForSequenceClassification.from_pretrained(
    "bert-base-chinese",
    num_labels=len(relation_types)
)

# 输入: [CLS] 爱因斯坦 [SEP] 德国 [SEP]
# 标签: birthPlace

一句话总结:知识图谱的构建是"抽取 → 链接 → 推理"的三段式流水线,每一步都需要领域知识和工程能力的结合。


3. 知识推理

3.1 基于规则的推理

% Datalog 风格规则
% 规则:如果 X 出生在 Y,Y 的首都是 Z,那么 X 的国籍是 Y
nationality(X, Y) :- birthPlace(X, Y), country(Y).

% 传递闭包
influences(X, Z) :- influences(X, Y), influences(Y, Z).

3.2 基于嵌入的推理

知识图谱嵌入(KGE)将实体和关系映射到低维向量空间:

# 使用 PyTorch Geometric 或 DGL-KE 训练嵌入
# TransE 模型:v_h + v_r ≈ v_t(头实体 + 关系 ≈ 尾实体)

import torch
import torch.nn as nn

class TransE(nn.Module):
    def __init__(self, num_entities, num_relations, dim):
        super().__init__()
        self.entity_embeddings = nn.Embedding(num_entities, dim)
        self.relation_embeddings = nn.Embedding(num_relations, dim)
        
    def score(self, heads, relations, tails):
        h = self.entity_embeddings(heads)
        r = self.relation_embeddings(relations)
        t = self.entity_embeddings(tails)
        return -torch.norm(h + r - t, p=1, dim=1)  # 负距离作为得分

嵌入训练完成后,可以进行链路预测:给定头实体和关系,预测最可能的尾实体。

3.3 路径推理

// 两跳推理查询
MATCH (einstein:Person {name: "爱因斯坦"})-[:DEVELOPED]->(theory)-[:INFLUENCES]->(field)
RETURN theory.name, field.name

// 多跳路径推理:X 的导师的导师是谁
MATCH (student:Person {name: "学生A"})-[:MENTORED_BY*1..3]->(ancestor:Person)
RETURN DISTINCT ancestor.name

一句话总结:知识推理让图谱"活"起来——规则推理精确但覆盖面有限,嵌入推理覆盖面广但可解释性差,二者各有适用场景。


4. KG + LLM:检索增强生成(RAG)

大语言模型有幻觉问题(hallucination)——一本正经地编造事实。知识图谱可以通过检索增强来缓解这个问题。

4.1 标准 RAG vs KG-RAG

传统 RAG:
  用户提问 → 向量化 → 向量数据库检索 → 将文本块喂给 LLM → 生成回答

KG-RAG:
  用户提问 → 实体识别 → 知识图谱子图检索 → 将结构化知识喂给 LLM → 生成回答

4.2 KG-RAG 实现模式

from neo4j import GraphDatabase
from openai import OpenAI

class KGRAG:
    def __init__(self, neo4j_uri, openai_key):
        self.driver = GraphDatabase.driver(neo4j_uri, auth=("neo4j", "password"))
        self.llm = OpenAI(api_key=openai_key)
    
    def retrieve_subgraph(self, entities):
        """检索与实体相关的子图"""
        with self.driver.session() as session:
            result = session.run("""
                MATCH (e)-[r]-(related)
                WHERE e.name IN $entities
                RETURN e.name AS source, type(r) AS relation,
                       related.name AS target, r.description AS desc
                LIMIT 30
            """, entities=entities)
            return [record.data() for record in result]
    
    def answer(self, question):
        # Step 1: 从问题中提取实体(可用 LLM 或 NER 模型)
        entities = self.extract_entities(question)
        
        # Step 2: 检索知识图谱子图
        subgraph = self.retrieve_subgraph(entities)
        
        # Step 3: 将子图转为文本上下文
        context = self.subgraph_to_text(subgraph)
        
        # Step 4: LLM 生成回答
        prompt = f"""基于以下知识回答用户问题。
知识:{context}
问题:{question}
如果不确定,请直接说明知识不足。"""
        
        response = self.llm.chat.completions.create(
            model="gpt-4o",
            messages=[{"role": "user", "content": prompt}]
        )
        return response.choices[0].message.content

    def extract_entities(self, text):
        # 简化版:关键词匹配(生产环境使用 NER 模型)
        known_entities = ["爱因斯坦", "相对论", "德国", "量子力学"]
        return [e for e in known_entities if e in text]
    
    def subgraph_to_text(self, subgraph):
        facts = []
        for edge in subgraph:
            facts.append(f"{edge['source']} 的 {edge['relation']} 是 {edge['target']}。")
        return "\n".join(facts)

一句话总结:KG-RAG 的核心优势是"结构化 + 可验证"——知识图谱提供的不是模糊相关的文本块,而是精确的三元组事实,让 LLM 的回答有据可查。


5. 应用场景

行业应用典型 KG
搜索引擎知识卡片、实体理解Google Knowledge Graph、Baidu Knowledge Graph
电商商品知识关联、智能导购淘宝商品知识图谱、Amazon Product Graph
金融企业关联分析、反欺诈企业股权穿透图谱、关联交易识别
医疗药物相互作用、辅助诊断医学知识图谱(UMLS、CN-DRG)
制造供应链溯源、设备维护工业知识图谱(设备-故障-维修方案)
政务一网通办、政策关联政务知识图谱(事项-材料-部门)

一句话总结:知识图谱已经从搜索引擎的后台技术,渗透到电商、金融、医疗、政务等几乎所有行业的智能化升级中。


6. 总结

知识图谱的核心认知:

  1. 三元组是世界观的抽象:任何复杂知识都可以拆解为 (实体, 关系, 实体) 的基本单元
  2. 构建是难点,推理是价值:高质量的知识抽取和实体对齐是最大的工程挑战
  3. RDF 代表标准,属性图代表效率:根据互操作性需求选择数据模型
  4. KG 是 LLM 的重要补充:结构化知识让生成式 AI 更可靠、更可解释

延伸阅读:

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「graphdb」更多文章

  1. 查询缓存与物化视图
  2. 图数据测试策略与回归验证
  3. 图数据库并发控制与批量更新