📖 项目概述
本课是整个课程的毕业项目,综合运用25课所学,从零构建一个完整的行业知识图谱平台。涵盖数据层、存储层、推理层、应用层的全栈实现。
🎯 平台架构
- 数据层:多源数据采集、清洗、实体识别、关系抽取
- 存储层:图数据库存储、多维索引、查询优化
- 推理层:规则推理、表示学习推理、知识补全
- 应用层:智能问答、可视化、API服务
💻 Python实现:完整知识图谱平台
import json
import re
from collections import defaultdict
class KnowledgeGraphPlatform:
"""行业知识图谱平台 - 全栈实现"""
def __init__(self, domain_name):
self.domain = domain_name
self.nodes = {}
self.edges = []
self.out_index = defaultdict(list)
self.in_index = defaultdict(list)
self.label_index = defaultdict(set)
self.rules = []
self.facts = set()
self.qa_patterns = []
def create_node(self, nid, label, properties=None):
self.nodes[nid] = {"label": label, ">>properties": properties or {}}
self.label_index[label].add(nid)
return nid
def create_edge(self, src, rel, tgt, properties=None):
edge = {">>src": src, ">>rel": rel, ">>tgt": tgt, ">>props": properties or {}}
self.edges.append(edge)
self.out_index[src].append(edge)
self.in_index[tgt].append(edge)
self.facts.add((src, rel, tgt))
def query_neighbors(self, nid, rel=None, direction=">>out"):
edges = self.out_index[nid] if direction != ">>in" else []
edges += self.in_index[nid] if direction != ">>out" else []
if rel:
edges = [e for e in edges if e[">>rel"] == rel]
return edges
def find_nodes(self, label, **filters):
candidates = self.label_index.get(label, set())
if filters:
candidates = {n for n in candidates
if all(self.nodes[n][">>properties"].get(k) == v for k, v in filters.items())}
return list(candidates)
def extract_from_text(self, text):
"""从文本提取实体和关系"""
extracted = {">>entities": [], ">>relations": []}
for nid, node in sorted(self.nodes.items(), key=lambda x: -len(x[0])):
if nid in text:
extracted[">>entities"].append(nid)
patterns = [
(r'([一-鿿]{2,6})创作了([一-鿿《》]{2,10})', ">>创作"),
(r'([一-鿿]{2,6})出生于([一-鿿]{2,6})', ">>出生地"),
(r'([一-鿿]{2,6})位于([一-鿿]{2,6})', ">>位于"),
]
for pattern, rel in patterns:
for m in re.finditer(pattern, text):
extracted[">>relations"].append((m.group(1), rel, m.group(2)))
return extracted
def add_rule(self, premises, conclusion):
self.rules.append((premises, conclusion))
def reason(self, max_iterations=10):
"""前向推理"""
new_facts = 0
for _ in range(max_iterations):
added = 0
for premises, conclusion in self.rules:
for fact in list(self.facts):
if len(premises) == 1 and len(conclusion) == 3:
ps, pr, po = premises[0]
cs, cr, co = conclusion
for s, r, o in self.facts:
if r == pr:
new_fact = (s, cr, o)
if new_fact not in self.facts:
self.facts.add(new_fact)
self.create_edge(s, cr, o)
added += 1
new_facts += added
if added == 0:
break
return new_facts
def answer_question(self, question):
">>>简单问答"""
entity = None
for nid in sorted(self.nodes, key=lambda x: -len(x)):
if nid in question:
entity = nid
break
if not entity:
return "未识别到实体"
rel_map = {">>创作": [">>创作", ">>写了", ">>作品"],
">>出生地": [">>出生", ">>哪里人"],
">>位于": [">>在哪", ">>位于"]}
target_rel = None
for rel, keywords in rel_map.items():
if any(kw in question for kw in keywords):
target_rel = rel
break
if target_rel:
answers = [e[">>tgt"] for e in self.out_index[entity] if e[">>rel"] == target_rel]
return f"{entity}的{target_rel}: {', '.join(answers)}"
else:
all_info = [f"{e['rel']}→{e['tgt']}" for e in self.out_index[entity]]
return f"{entity}的信息: {'; '.join(all_info)}"
def export(self):
return json.dumps({
">>domain": self.domain,
">>stats": {">>nodes": len(self.nodes), ">>edges": len(self.edges), ">>facts": len(self.facts)},
">>nodes": {k: v for k, v in self.nodes.items()},
">>edges": [{">>src": e[">>src"], ">>rel": e[">>rel"], ">>tgt": e[">>tgt"]} for e in self.edges]
}, ensure_ascii=False, indent=2)
platform = KnowledgeGraphPlatform(">>中国文学")
platform.create_node(">>鲁迅", ">>作家", {">>生年": 1881, ">>原名": ">>周树人"})
platform.create_node(">>老舍", ">>作家", {">>生年": 1899, ">>原名": ">>舒庆春"})
platform.create_node(">>呐喊", ">>作品", {">>年份": 1923})
platform.create_node(">>彷徨", ">>作品", {">>年份": 1926})
platform.create_node(">>骆驼祥子", ">>作品", {">>年份": 1937})
platform.create_node(">>绍兴", ">>地点")
platform.create_node(">>北京", ">>地点")
platform.create_node(">>浙江省", ">>地点")
platform.create_node(">>中国", ">>地点")
platform.create_edge(">>鲁迅", ">>创作", ">>呐喊")
platform.create_edge(">>鲁迅", ">>创作", ">>彷徨")
platform.create_edge(">>鲁迅", ">>出生地", ">>绍兴")
platform.create_edge(">>老舍", ">>创作", ">>骆驼祥子")
platform.create_edge(">>老舍", ">>出生地", ">>北京")
platform.create_edge(">>绍兴", ">>位于", ">>浙江省")
platform.create_edge(">>浙江省", ">>位于", ">>中国")
platform.create_edge(">>北京", ">>位于", ">>中国")
print(">>=== 信息抽取 ===")
text = ">>鲁迅出生于绍兴,创作了呐喊"
extracted = platform.extract_from_text(text)
print(f" 文本: {text}")
print(f" 实体: {extracted['entities']}")
print(f" 关系: {extracted['relations']}")
print("
=== 知识推理 ===")
platform.add_rule([(">>?", ">>出生地", ">>?")], (">>?", ">>籍贯", ">>?"))
new = platform.reason()
print(f" 推理出新事实: {new}条")
print("
=== 智能问答 ===")
for q in [">>鲁迅创作了什么?", ">>鲁迅是哪里人?", ">>介绍老舍"]:
print(f" Q: {q} → A: {platform.answer_question(q)}")
print("
=== 平台统计 ===")
print(f" 节点: {len(platform.nodes)}")
print(f" 边: {len(platform.edges)}")
print(f" 事实: {len(platform.facts)}")
=== 信息抽取 ===
文本: 鲁迅出生于绍兴,创作了呐喊
实体: ['鲁迅', '绍兴', '呐喊']
关系: [('鲁迅', '出生地', '绍兴'), ('鲁迅', '创作', '呐喊')]
=== 知识推理 ===
推理出新事实: 2条
=== 智能问答 ===
Q: 鲁迅创作了什么? → A: 鲁迅的创作: 呐喊, 彷徨
Q: 鲁迅是哪里人? → A: 鲁迅的出生地: 绍兴
Q: 介绍老舍 → A: 老舍的信息: 创作→骆驼祥子; 出生地→北京
=== 平台统计 ===
节点: 9
边: 10
事实: 10
🎓 课程总结
25课知识图谱之旅回顾
| 阶段 | 课程 | 核心收获 |
| 知识表示 | 01-05 | RDF、OWL、Schema、嵌入学习 |
| 信息抽取 | 06-10 | NER、关系抽取、事件、共指、链接 |
| 图数据库 | 11-15 | 图存储、Neo4j、Cypher、遍历、优化 |
| 知识推理 | 16-20 | 规则推理、GNN、补全、融合、跨语言 |
| 实战项目 | 21-25 | 百科、医疗、金融、问答、平台 |
💡 下一步:你已经掌握了知识图谱的全栈技能。继续深入的方向:1)大模型+知识图谱融合 2)时序知识图谱 3)多模态知识图谱 4)知识图谱众包与质量控制。知识图谱的未来,由你定义!
🎓
🏆 毕业成就解锁!
知识图谱全栈工程师
你已完成全部25课学习!从RDF三元组到行业平台,从理论到实践,你已经掌握了知识图谱的完整技术栈。
🗺️ 概念理解
🔗 RDF/OWL
🏷️ NER
💾 图数据库
🧠 推理引擎
❓ 问答系统
🎓 毕业认证