53. 知识图谱入门与构建¶
一句话说明:知识图谱是"用实体-关系-实体的网络结构来存储和推理知识"的技术——把散落在各处的知识点串成一张大网,让计算机不仅能存数据,还能像人一样"联想"和"推理"。
目录¶
- 什么是知识图谱
- 核心概念详解
- 知识图谱 vs 关系数据库 vs 向量数据库
- 知识图谱构建流程
- 常用工具
- LLM + 知识图谱(GraphRAG)
- 生信中的知识图谱
- Python 实操:用 NetworkX 构建基因互作网络
- 常见报错与解决方案
- 面试怎么答
- 速查表
- 延伸资源
1. 什么是知识图谱¶
1.1 白话解释¶
知识图谱(Knowledge Graph, KG) 就是一张"知识地图"。
想象你在画一张思维导图:中间写"2型糖尿病",拉一条线到"胰岛素抵抗"写上"病因",再拉一条线到"二甲双胍"写上"治疗药物",再拉一条线到"Akkermansia muciniphila"写上"相关菌群"。这张思维导图里的每个圆圈是"实体"(entity),每条连线是"关系"(relation)。把这种结构规模化,存到计算机里,就是知识图谱。
正式定义:知识图谱是一种用图结构(节点+边)来表示和存储知识的知识库。节点代表实体(如基因、疾病、药物),边代表实体之间的关系(如"抑制""表达""治疗")。根据 Wikipedia,知识图谱使用图结构的数据模型来表示和操作数据,存储实体的互连描述,同时编码这些实体底层的语义关系。
1.2 知识图谱的"前世今生"¶
| 时期 | 事件 | 意义 |
|---|---|---|
| 2001 年 | Tim Berners-Lee 提出语义网(Semantic Web) | 奠定了用结构化方式组织互联网知识的理念 |
| 2012 年 | Google 推出 Knowledge Graph | "知识图谱"概念正式火起来,搜索不再只是匹配关键词 |
| 2015-2020 年 | 各大公司构建行业知识图谱 | 金融风控、医疗诊断、推荐系统广泛应用 |
| 2023-2026 年 | LLM + KG(GraphRAG)兴起 | 大模型 + 知识图谱结合,解决幻觉问题 |
1.3 知识图谱能干什么¶
- 智能搜索:搜"糖尿病的治疗药物有哪些副作用",通过关系链自动推理
- 推荐系统:京东、淘宝用商品知识图谱做"猜你喜欢"
- 医学诊断辅助:症状→疾病→药物→禁忌的关系推理
- 生信研究:基因-疾病关联发现、药物靶点预测、蛋白质互作分析
2. 核心概念详解¶
2.1 三元组(Triple)¶
知识图谱最基本的单位,格式:(主语, 谓语, 宾语),也叫 (头实体, 关系, 尾实体)。
白话:就是一句最简单的"谁-怎么样-谁"。
例子:
(TP53, 抑制, 细胞增殖) → 基因TP53抑制细胞增殖
(二甲双胍, 治疗, 2型糖尿病) → 二甲双胍治疗2型糖尿病
(BRCA1, 关联, 乳腺癌) → BRCA1基因和乳腺癌有关联
白话比方:三元组就像一句主谓宾的句子。"小明(主)-喜欢(谓)-篮球(宾)"就是一个三元组。整个知识图谱就是由无数这样的简单句子组成的。
2.2 本体(Ontology)¶
白话解释:本体是"知识图谱的词典+语法规则"。它定义了: - 有哪些类别(class):比如"基因""疾病""药物""菌种" - 有哪些关系类型:比如"治疗""抑制""编码""互作" - 层级关系:比如"乳腺癌"是"癌症"的子类,"癌症"是"疾病"的子类
白话比方:
本体 = 字典 + 语法书
- 字典告诉你有哪些"词"可以用(实体类别和关系类别)
- 语法书告诉你"词"之间怎么组合才合法
比如:你不能写"TP53 治疗 大肠杆菌"(基因不能"治疗"菌),
因为本体规定"治疗"关系只能是"药物→疾病"。
生信中常见的本体:Gene Ontology(GO)、Disease Ontology(DO)、Human Phenotype Ontology(HPO)。
2.3 RDF(资源描述框架)¶
白话解释:RDF(Resource Description Framework)是 W3C 制定的一种数据格式标准,专门用来描述三元组。
根据 W3C 定义,RDF 是一种描述和交换图数据的方法,最初由万维网联盟(W3C)设计为元数据的数据模型。它用有向图的三元组语句表示:(1) 主语节点,(2) 从主语到宾语的弧(表示谓语),(3) 宾语节点。
白话比方:
三元组是"知识的内容",RDF 是"把知识写下来的格式"。
就像"你好"是内容,JSON/XML/CSV 是把它存下来的格式。
RDF 三元组示例(Turtle 格式):
<http://example.org/TP53> <http://example.org/inhibits> <http://example.org/CellProliferation> .
翻译:TP53 抑制 细胞增殖
2.4 SPARQL¶
白话解释:SPARQL(读作"sparkle")是专门查询 RDF 知识图谱的语言,地位相当于关系数据库的 SQL。
SPARQL 是一种 RDF 查询语言,即用于数据库的语义查询语言,能够检索和操作以 RDF 格式存储的数据。它由 W3C 标准化,SPARQL 1.0 于 2008 年成为官方推荐标准,SPARQL 1.1 于 2013 年发布。
# 查询所有和2型糖尿病相关的基因
SELECT ?gene ?relation
WHERE {
?gene ?relation <http://example.org/T2D> . # 找所有和T2D有关系的基因
?gene a <http://example.org/Gene> . # 限定类型是基因
}
2.5 属性图(Property Graph)¶
白话解释:属性图是另一种存储知识图谱的模型,比 RDF 更灵活、更直观。
| 特性 | RDF 图 | 属性图 |
|---|---|---|
| 节点 | 用 URI 标识 | 可以有任意属性(键值对) |
| 边 | 只有类型 | 可以有类型 + 属性(如权重、置信度) |
| 查询语言 | SPARQL | Cypher(Neo4j)/ Gremlin |
| 适合场景 | 语义网、开放数据集互联 | 企业应用、社交网络、生信网络 |
| 白话区别 | 更学术、标准化 | 更工程化、灵活好用 |
属性图示例(Cypher 语法):
(:Gene {name:"TP53", chromosome:"17"}) ← 节点有属性
-[:INHIBITS {confidence:0.95}]-> ← 边也有属性
(:BiologicalProcess {name:"CellProliferation"})
3. 知识图谱 vs 关系数据库 vs 向量数据库¶
这三种是完全不同的数据存储思路,别搞混:
| 对比项 | 关系数据库(MySQL) | 向量数据库(ChromaDB) | 知识图谱(Neo4j) |
|---|---|---|---|
| 数据模型 | 表格(行+列) | 高维向量 | 图(节点+边) |
| 存什么 | 结构化数据 | 文本/图片的数字表示 | 实体之间的关系 |
| 查询方式 | SQL 精确匹配 | 相似度搜索(最近邻) | 图遍历/路径查询 |
| 擅长回答 | "TP53 在哪个染色体上?" | "哪些基因和 TP53 描述最像?" | "TP53 通过哪些路径影响糖尿病?" |
| 推理能力 | 无(只能查存进去的数据) | 无(只能找相似的) | 有(能沿关系链推理新知识) |
| 索引类型 | B-Tree / Hash | HNSW / IVF | 图索引(邻接表) |
| 典型产品 | MySQL / PostgreSQL | FAISS / Milvus / ChromaDB | Neo4j / JanusGraph / Amazon Neptune |
白话总结: - 关系数据库像 Excel 表格——查"某一行某一列"的精确数据 - 向量数据库像"以图搜图"——找最相似的内容 - 知识图谱像思维导图——沿着关系链条做推理和联想
三者可以互补:很多系统同时使用。比如 GraphRAG 就是"向量数据库做初步检索 + 知识图谱做关系推理 + LLM 生成回答"。
4. 知识图谱构建流程¶
构建知识图谱就像从一堆论文里手动画思维导图,但用程序自动化:
4.1 知识抽取(Knowledge Extraction)¶
白话:从非结构化文本(论文、报告)或半结构化数据(HTML、表格)中,把有用的知识"挖"出来。
4.2 实体识别(Named Entity Recognition, NER)¶
白话:从文本中找出"哪些词是基因名、哪些是疾病名、哪些是药物名"。
常用工具: - 通用 NER:spaCy、NLTK、HuggingFace NER 模型 - 生信 NER:PubTator(NCBI 的生物医学文本挖掘工具)、BioBERT、SciSpacy
4.3 关系抽取(Relation Extraction)¶
白话:识别出实体后,判断它们之间是什么关系。"TP53 抑制 细胞增殖"中,"抑制"就是关系。
方法: - 规则匹配:用正则或依存句法树提取 - 监督学习:训练分类模型判断两个实体间的关系类型 - LLM 抽取:直接让 GPT/Claude 从文本中提取三元组(2024-2026 年主流方式)
4.4 知识融合(Knowledge Fusion)¶
白话:不同数据源对同一个东西可能叫不同名字。比如"大肠杆菌"="E. coli"="Escherichia coli",需要合并成一个实体。
关键任务: - 实体对齐:把指代同一事物的不同名称统一(Entity Alignment) - 实体消歧:区分同名不同义(如 "JAK" 可能是基因名也可能是人名) - 冲突解决:不同来源说的不一样时,按可信度排序
4.5 知识存储¶
把处理好的三元组存入图数据库:
| 存储方案 | 适合场景 | 查询语言 |
|---|---|---|
| Neo4j | 企业级图数据库,功能强大 | Cypher |
| RDF 三元组存储(Virtuoso、GraphDB) | 语义网、开放数据集 | SPARQL |
| NetworkX(内存图) | 小规模分析、原型验证 | Python API |
| Amazon Neptune | 云上大规模图 | Cypher / SPARQL |
4.6 知识推理(Knowledge Reasoning)¶
白话:根据已有的关系,推断出新的关系。
推理方法: - 基于规则:手写推理规则(如 TransE、RotatE 等嵌入模型) - 知识图谱嵌入:把实体和关系映射到向量空间,用向量运算做推理 - 图神经网络(GNN):用深度学习在图上做预测(链接预测、节点分类)
5. 常用工具¶
5.1 Neo4j(图数据库)¶
Neo4j 是一个图数据库管理系统,由 Neo4j Inc. 开发。它用 Java 实现,通过 Cypher 查询语言访问,支持 ACID 事务,是目前最流行的图数据库。
// 创建基因节点
CREATE (:Gene {name: 'TP53', chromosome: '17p13.1'})
// 创建疾病节点
CREATE (:Disease {name: 'Breast Cancer', icd10: 'C50'})
// 创建关系
MATCH (g:Gene {name: 'TP53'}), (d:Disease {name: 'Breast Cancer'})
CREATE (g)-[:ASSOCIATED_WITH {evidence: 'GWAS', pvalue: 1e-8}]->(d)
// 查询:找出和乳腺癌相关的所有基因
MATCH (g:Gene)-[:ASSOCIATED_WITH]->(d:Disease {name: 'Breast Cancer'})
RETURN g.name, g.chromosome
安装:Docker 一键启动(推荐)
docker pull neo4j:5-community # 拉取社区版镜像
docker run -d \
--name neo4j \
-p 7474:7474 -p 7687:7687 \ # 7474=Web界面, 7687=Bolt协议
-e NEO4J_AUTH=neo4j/password \ # 设置用户名密码
neo4j:5-community
# 浏览器访问 http://localhost:7474 即可看到可视化界面
5.2 NetworkX(Python 图分析库)¶
NetworkX 是 Python 的图/网络分析库(当前版本 3.6.1),适合中小规模图的分析和可视化。不需要安装数据库,纯 Python 内存操作。
适合场景:学术研究、原型验证、几万节点以内的图分析
5.3 py2neo(Python 操作 Neo4j)¶
py2neo 是从 Python 连接和操作 Neo4j 的客户端库和工具包,提供了面向对象的 API,比直接写 Cypher 更 Pythonic。
from py2neo import Graph, Node, Relationship # 导入核心类
graph = Graph("bolt://localhost:7687", auth=("neo4j", "password")) # 连接数据库
# 创建节点
gene = Node("Gene", name="TP53", chromosome="17") # 创建基因节点
disease = Node("Disease", name="Breast Cancer") # 创建疾病节点
# 创建关系并提交
rel = Relationship(gene, "ASSOCIATED_WITH", disease) # 创建关系
graph.create(rel) # 写入数据库
注意:py2neo 已不再积极维护(最后更新 2023 年)。Neo4j 官方推荐使用
neo4jPython driver:pip install neo4j
5.4 工具选型指南¶
| 场景 | 推荐工具 | 理由 |
|---|---|---|
| 快速原型/学术研究 | NetworkX | 零依赖,纯 Python,适合几千到几万节点 |
| 生产级图存储 | Neo4j | ACID 事务,可视化界面,Cypher 强大 |
| 语义网/开放数据 | GraphDB / Virtuoso | 原生支持 RDF + SPARQL |
| 大规模分布式图 | Amazon Neptune / TigerGraph | 云原生,水平扩展 |
| LLM + 知识图谱 | Microsoft GraphRAG + Neo4j | 最成熟的 GraphRAG 方案 |
6. LLM + 知识图谱(GraphRAG)¶
6.1 为什么需要 GraphRAG¶
普通 RAG(检索增强生成)的问题: - 只能做局部检索——找到和问题最相似的几个文档片段 - 无法回答全局性问题——"整个数据集里最重要的主题是什么?" - 缺乏多跳推理——"A 和 D 之间通过 B、C 有什么关联?"
GraphRAG 的解决方案:先把文档构建成知识图谱,再在图上做推理+检索,最后交给 LLM 生成回答。
6.2 微软 GraphRAG¶
微软于 2024 年开源的 GraphRAG 项目是目前最成熟的方案。根据其官方描述,GraphRAG 是一个数据管道和转换套件,旨在使用 LLM 的能力从非结构化文本中提取有意义的结构化数据。它使用知识图谱记忆结构来增强 LLM 输出。
核心流程:
两种查询模式: - Local Search(局部搜索):适合"TP53 有什么功能?"这类具体问题 - Global Search(全局搜索):适合"这批数据的主要发现是什么?"这类综合问题
6.3 GraphRAG 快速体验¶
# 安装(需要 Python 3.10+)
pip install graphrag # 安装 GraphRAG
# 初始化项目
graphrag init --root ./my_project # 创建配置文件
# 配置 settings.yaml,填入 LLM API key
# 建立索引(将文档转化为知识图谱)
graphrag index --root ./my_project # 开始构建图谱
# 查询
graphrag query --root ./my_project \
--method local \ # 局部搜索模式
--query "TP53基因有哪些功能?" # 你的问题
注意:GraphRAG 索引过程会大量调用 LLM API,成本较高。建议先用小数据集测试。
6.4 GraphRAG vs 普通 RAG¶
| 对比项 | 普通 RAG | GraphRAG |
|---|---|---|
| 检索方式 | 向量相似度 | 图遍历 + 向量相似度 |
| 推理能力 | 单跳(找最相似的片段) | 多跳(沿关系链推理) |
| 全局问题 | 表现差 | 通过社区摘要回答全局问题 |
| 构建成本 | 低(只需 Embedding) | 高(需要 LLM 抽取实体关系) |
| 适合场景 | 简单问答 | 复杂分析、报告生成、全局总结 |
7. 生信中的知识图谱¶
知识图谱在生物信息学中有重要应用。根据近年文献,知识图谱越来越多地用于科学研究,特别是在基因组学、蛋白质组学和系统生物学领域。
7.1 基因-疾病关系图¶
典型数据库: - DisGeNET:收录了基因/变异与疾病的关联,包含 >1.1M 基因-疾病关联 - OMIM:人类孟德尔遗传在线数据库 - ClinVar:变异-疾病关联数据库
应用示例:
查询"2型糖尿病相关的所有基因"
→ DisGeNET 返回 TCF7L2、PPARG、KCNJ11、SLC30A8 等数百个基因
→ 按证据等级(GDA score)排序
→ 结合通路分析,发现主要涉及胰岛素信号通路、糖代谢通路
7.2 蛋白质互作网络(PPI Network)¶
典型数据库: - STRING:蛋白质互作数据库(>67M 蛋白质,>20B 互作对) - BioGRID:基因和蛋白质互作数据库 - IntAct:分子互作数据库
7.3 药物-靶点知识图谱¶
典型数据库: - DrugBank:药物信息 + 靶点数据库 - ChEMBL:生物活性化合物数据库 - TTD(Therapeutic Target Database):治疗靶点数据库
应用场景 — 药物重定位(Drug Repurposing):
已知:药物A → 靶向蛋白质B → 蛋白质B参与通路C → 通路C关联疾病D
推断:药物A 可能治疗 疾病D
真实案例:通过知识图谱推理,发现已有药物对 COVID-19 可能有效
7.4 示例项目可以怎么用¶
结合该 T2D 肠道菌群项目:
构建一个小型知识图谱:
菌种(如 Akkermansia)→ 产生 → 代谢物(如短链脂肪酸)
代谢物 → 影响 → 宿主通路(如胰岛素信号通路)
宿主通路 → 关联 → 疾病(2型糖尿病)
菌种 → 差异丰度 → 疾病组/健康组
用 NetworkX 或 Neo4j 存储和可视化,面试时展示"我不仅做了统计分析,
还构建了菌群-代谢-疾病的知识图谱来理解机制"。
8. Python 实操:用 NetworkX 构建基因互作网络¶
8.1 完整代码(带详细中文注释)¶
"""
实操:用 NetworkX 构建一个简单的基因-疾病-药物知识图谱
场景:模拟 2 型糖尿病相关的基因、通路、药物关系网络
"""
import networkx as nx # 导入 NetworkX 图分析库
import matplotlib.pyplot as plt # 导入绑图库
import matplotlib # 导入 matplotlib 用于设置中文字体
# ============================================================
# 第一步:创建有向图(关系有方向,如"基因A → 抑制 → 通路B")
# ============================================================
G = nx.DiGraph() # DiGraph = Directed Graph,有向图
# ============================================================
# 第二步:添加节点(实体),每个节点带有属性
# ============================================================
# 基因节点
G.add_node("TCF7L2", type="gene", description="转录因子,T2D最强风险基因") # 添加基因节点
G.add_node("PPARG", type="gene", description="过氧化物酶体增殖活化受体γ") # 另一个T2D相关基因
G.add_node("INS", type="gene", description="胰岛素基因") # 胰岛素基因
G.add_node("SLC30A8", type="gene", description="锌转运蛋白,影响胰岛素分泌") # 锌转运体基因
G.add_node("KCNJ11", type="gene", description="钾通道基因,调控胰岛素释放") # 钾通道基因
# 疾病节点
G.add_node("T2D", type="disease", description="2型糖尿病") # 疾病节点
G.add_node("Obesity", type="disease", description="肥胖症") # 肥胖症
# 药物节点
G.add_node("Metformin", type="drug", description="二甲双胍,一线降糖药") # 二甲双胍
G.add_node("Pioglitazone", type="drug", description="吡格列酮,PPARγ激动剂") # 吡格列酮
# 通路节点
G.add_node("InsulinPathway", type="pathway", description="胰岛素信号通路") # 胰岛素通路
G.add_node("WntPathway", type="pathway", description="Wnt信号通路") # Wnt通路
# 菌群节点(结合你的研究方向)
G.add_node("Akkermansia", type="microbe", description="嗜黏蛋白阿克曼菌") # 有益菌
G.add_node("SCFA", type="metabolite", description="短链脂肪酸") # 代谢物
# ============================================================
# 第三步:添加边(关系),每条边带有关系类型和权重
# ============================================================
# 基因-疾病关联
G.add_edge("TCF7L2", "T2D", relation="risk_gene_for", weight=0.95) # TCF7L2是T2D风险基因
G.add_edge("PPARG", "T2D", relation="risk_gene_for", weight=0.88) # PPARG也是T2D风险基因
G.add_edge("INS", "T2D", relation="risk_gene_for", weight=0.85) # 胰岛素基因关联T2D
G.add_edge("SLC30A8", "T2D", relation="risk_gene_for", weight=0.80) # SLC30A8关联T2D
G.add_edge("KCNJ11", "T2D", relation="risk_gene_for", weight=0.82) # KCNJ11关联T2D
G.add_edge("PPARG", "Obesity", relation="risk_gene_for", weight=0.75) # PPARG也关联肥胖
# 基因-通路关系
G.add_edge("TCF7L2", "WntPathway", relation="participates_in", weight=0.9) # TCF7L2参与Wnt通路
G.add_edge("PPARG", "InsulinPathway", relation="regulates", weight=0.85) # PPARG调控胰岛素通路
G.add_edge("INS", "InsulinPathway", relation="participates_in", weight=0.95) # 胰岛素参与胰岛素通路
# 药物-基因/通路关系
G.add_edge("Pioglitazone", "PPARG", relation="targets", weight=0.92) # 吡格列酮靶向PPARG
G.add_edge("Metformin", "InsulinPathway", relation="modulates", weight=0.88) # 二甲双胍调节胰岛素通路
# 药物-疾病关系
G.add_edge("Metformin", "T2D", relation="treats", weight=0.95) # 二甲双胍治疗T2D
G.add_edge("Pioglitazone", "T2D", relation="treats", weight=0.80) # 吡格列酮治疗T2D
# 菌群相关关系
G.add_edge("Akkermansia", "SCFA", relation="produces", weight=0.7) # Akkermansia产生SCFA
G.add_edge("SCFA", "InsulinPathway", relation="activates", weight=0.6) # SCFA激活胰岛素通路
G.add_edge("Metformin", "Akkermansia", relation="enriches", weight=0.65) # 二甲双胍富集Akkermansia
# ============================================================
# 第四步:图分析——计算节点重要性
# ============================================================
# 度中心性:一个节点连了多少边(越多越重要)
degree_cent = nx.degree_centrality(G) # 计算每个节点的度中心性
# 介数中心性:一个节点在多少最短路径上(越多说明越是"桥梁")
betweenness = nx.betweenness_centrality(G) # 计算介数中心性
# PageRank:类似Google排名,被重要节点连接的节点更重要
pagerank = nx.pagerank(G, weight='weight') # 计算PageRank值
# 打印分析结果
print("=" * 60)
print("节点重要性排名(按 PageRank)")
print("=" * 60)
sorted_pr = sorted(pagerank.items(), key=lambda x: x[1], reverse=True) # 按PageRank降序排列
for node, score in sorted_pr: # 遍历排序后的结果
node_type = G.nodes[node].get('type', '?') # 获取节点类型
print(f" {node:18s} (type={node_type:10s}) PageRank={score:.4f}" # 格式化输出
f" Degree={degree_cent[node]:.3f}" # 度中心性
f" Betweenness={betweenness[node]:.3f}") # 介数中心性
# ============================================================
# 第五步:路径查询——药物如何通过知识图谱关联到疾病
# ============================================================
print("\n" + "=" * 60)
print("路径分析:Akkermansia 如何与 T2D 关联?")
print("=" * 60)
# 查找所有简单路径(不重复经过同一节点)
for path in nx.all_simple_paths(G, "Akkermansia", "T2D", cutoff=4): # cutoff=最多经过4步
relations = [] # 存储路径上的关系
for i in range(len(path) - 1): # 遍历路径中相邻节点对
edge_data = G.edges[path[i], path[i+1]] # 获取边的属性
relations.append(edge_data.get('relation', '?')) # 提取关系名
path_str = "" # 构建可读的路径字符串
for i, node in enumerate(path): # 遍历路径中的节点
path_str += node # 添加节点名
if i < len(relations): # 如果后面还有关系
path_str += f" --[{relations[i]}]--> " # 添加关系箭头
print(f" 路径: {path_str}") # 打印完整路径
# ============================================================
# 第六步:可视化
# ============================================================
plt.figure(figsize=(14, 10)) # 设置画布大小
# 按节点类型分配颜色
color_map = { # 定义颜色映射
"gene": "#4ECDC4", # 青绿色 = 基因
"disease": "#FF6B6B", # 红色 = 疾病
"drug": "#45B7D1", # 蓝色 = 药物
"pathway": "#96CEB4", # 绿色 = 通路
"microbe": "#FFEAA7", # 黄色 = 微生物
"metabolite": "#DDA0DD", # 紫色 = 代谢物
}
node_colors = [color_map.get(G.nodes[n].get('type', ''), '#999') # 根据类型获取颜色
for n in G.nodes()] # 对每个节点
# 按 PageRank 调整节点大小
node_sizes = [pagerank[n] * 8000 + 500 for n in G.nodes()] # PageRank越大节点越大
# 布局算法:spring_layout 模拟弹簧力,让图看起来更美观
pos = nx.spring_layout(G, k=2, seed=42) # k控制节点间距,seed固定布局
# 画边(带箭头)
nx.draw_networkx_edges(G, pos, # 画边
edge_color='#888888', # 灰色边
arrows=True, # 显示箭头
arrowsize=15, # 箭头大小
width=1.5, # 线宽
alpha=0.6) # 透明度
# 画节点
nx.draw_networkx_nodes(G, pos, # 画节点
node_color=node_colors, # 节点颜色
node_size=node_sizes, # 节点大小
edgecolors='black', # 节点边框颜色
linewidths=1.5) # 边框线宽
# 画节点标签
nx.draw_networkx_labels(G, pos, font_size=9, font_weight='bold') # 节点名称
# 画边标签(关系名)
edge_labels = {(u, v): d['relation'] # 提取关系名作为边标签
for u, v, d in G.edges(data=True)}
nx.draw_networkx_edge_labels(G, pos, # 画边上的关系标签
edge_labels=edge_labels,
font_size=7,
font_color='#555555')
plt.title("T2D Gene-Disease-Drug Knowledge Graph", fontsize=16, fontweight='bold') # 标题
plt.legend(handles=[ # 添加图例
plt.Line2D([0], [0], marker='o', color='w', markerfacecolor=c, markersize=12, label=t)
for t, c in color_map.items()
], loc='upper left', fontsize=10)
plt.axis('off') # 隐藏坐标轴
plt.tight_layout() # 自动调整布局
plt.savefig("t2d_knowledge_graph.png", dpi=150, bbox_inches='tight') # 保存图片
plt.show() # 显示图形
print("\n图谱已保存为 t2d_knowledge_graph.png")
# ============================================================
# 第七步:导出为 GraphML 格式(可导入 Neo4j / Cytoscape)
# ============================================================
nx.write_graphml(G, "t2d_knowledge_graph.graphml") # 导出为标准 GraphML 格式
print("图谱数据已导出为 t2d_knowledge_graph.graphml") # 可以用 Cytoscape 打开可视化
8.2 运行方法¶
# 激活 conda 环境
conda activate bioinfo # 使用你的生信环境
# 安装依赖(如果没装的话)
pip install networkx matplotlib # NetworkX + 绑图
# 运行脚本
python knowledge_graph_demo.py # 执行
8.3 预期输出¶
============================================================
节点重要性排名(按 PageRank)
============================================================
T2D (type=disease ) PageRank=0.1842 Degree=0.538 Betweenness=0.103
InsulinPathway (type=pathway ) PageRank=0.1356 Degree=0.385 Betweenness=0.282
PPARG (type=gene ) PageRank=0.0912 Degree=0.308 Betweenness=0.154
...
============================================================
路径分析:Akkermansia 如何与 T2D 关联?
============================================================
路径: Akkermansia --[produces]--> SCFA --[activates]--> InsulinPathway ...
9. 常见报错与解决方案¶
| 报错 / 问题 | 原因 | 解决方案 |
|---|---|---|
ModuleNotFoundError: No module named 'networkx' | 没安装 NetworkX | pip install networkx |
neo4j.exceptions.ServiceUnavailable | Neo4j 没启动或端口不对 | 检查 Docker 是否运行:docker ps |
py2neo.errors.ConnectionRefused | 连接被拒绝 | 确认 Neo4j 端口 7687 开放,密码正确 |
| NetworkX 画图中文乱码 | matplotlib 缺中文字体 | plt.rcParams['font.sans-serif'] = ['SimHei'] |
graphrag index 报 API key 错误 | 没配置 LLM API | 编辑 settings.yaml,填入正确的 API key |
| 知识图谱节点太多画出来是一团乱 | 节点数量超过可视化极限 | 筛选关键节点(如只画 PageRank top 50),或用 Gephi / Cytoscape |
Neo4j 内存不足 OutOfMemoryError | 图太大,默认内存不够 | 修改 neo4j.conf 中 dbms.memory.heap.max_size=4G |
10. 面试怎么答¶
Q1:什么是知识图谱?和传统数据库有什么区别?¶
知识图谱是用图结构(节点+边)来存储知识的数据库。核心单位是三元组:(实体, 关系, 实体)。和传统关系数据库最大的区别是:关系数据库用表格存数据,查询靠 SQL 做精确匹配;知识图谱用图存数据,可以沿着关系链做多跳推理,发现隐含的知识。比如通过"药物→靶点→通路→疾病"这条关系链做药物重定位。
Q2:知识图谱在生信中有哪些应用?¶
主要有三个方面:第一,基因-疾病关联分析,比如用 DisGeNET 查某个疾病关联的所有风险基因;第二,蛋白质互作网络(PPI),用 STRING 数据库构建互作图,做 Hub 基因筛选和模块分析;第三,药物重定位,通过知识图谱推理已有药物对新疾病的潜在治疗作用。在该 T2D 项目中,也可以构建"菌群-代谢物-宿主通路-疾病"的小型知识图谱来辅助理解机制。
Q3:请解释 RDF 和属性图的区别。¶
两者都是知识图谱的存储模型。RDF 是 W3C 标准,用 URI 标识每个实体,三元组格式是(主语, 谓语, 宾语),查询用 SPARQL。优点是标准化程度高,适合开放数据集互联。属性图模型中,节点和边都可以带任意属性(键值对),查询用 Cypher(Neo4j),更灵活更工程化。生信研究中,做蛋白质互作网络分析用属性图更方便,因为边上需要存权重、实验方法等属性。
Q4:什么是 GraphRAG?和普通 RAG 有什么区别?¶
GraphRAG 是微软提出的方法,核心思路是先用 LLM 从文档中抽取实体和关系构建知识图谱,再通过社区检测算法(Leiden)做层次化聚类和摘要。和普通 RAG 的区别:普通 RAG 只能做向量相似度检索,找最相关的文本片段;GraphRAG 能做多跳推理和全局总结,比如"这批数据最重要的发现是什么"这种全局性问题,普通 RAG 答不好,GraphRAG 通过社区摘要可以回答。代价是构建成本更高。
Q5:你如何用 Python 构建一个简单的知识图谱?¶
用 NetworkX 库。首先用
nx.DiGraph()创建有向图,然后用add_node()添加实体节点,每个节点带类型和描述属性;用add_edge()添加关系边,带关系名和权重属性。分析方面,可以计算度中心性找出连接最多的 Hub 节点,计算介数中心性找出关键"桥梁"节点,用all_simple_paths()查找两个实体之间的所有路径。如果数据量大,建议用 Neo4j 存储,用 py2neo 或 neo4j Python driver 操作。
11. 速查表¶
核心概念速查¶
| 概念 | 一句话解释 | 类比 |
|---|---|---|
| 知识图谱 | 用"实体-关系-实体"组成的网络存知识 | 超大号思维导图 |
| 三元组 | (头实体, 关系, 尾实体) | 一句主谓宾的句子 |
| 本体 | 定义有哪些类和关系的"规则书" | 字典 + 语法规则 |
| RDF | W3C 标准的图数据格式 | 知识的"存储格式" |
| SPARQL | 查询 RDF 图的语言 | 知识图谱的 SQL |
| 属性图 | 节点和边都能带属性的图模型 | 更灵活的 RDF |
| Cypher | Neo4j 的查询语言 | 属性图的 SQL |
构建流程速查¶
Python NetworkX 常用操作速查¶
import networkx as nx # 导入
G = nx.DiGraph() # 创建有向图
G = nx.Graph() # 创建无向图
G.add_node("A", type="gene") # 添加带属性的节点
G.add_edge("A", "B", relation="inhibits") # 添加带属性的边
G.nodes() # 所有节点
G.edges(data=True) # 所有边(含属性)
G.degree("A") # 节点A的度
G.neighbors("A") # 节点A的邻居
nx.degree_centrality(G) # 度中心性
nx.betweenness_centrality(G) # 介数中心性
nx.pagerank(G) # PageRank
nx.shortest_path(G, "A", "B") # 最短路径
nx.all_simple_paths(G, "A", "B", cutoff=3) # 所有简单路径
nx.write_graphml(G, "out.graphml") # 导出 GraphML
nx.read_graphml("out.graphml") # 读取 GraphML
Neo4j Cypher 常用操作速查¶
CREATE (:Gene {name:'TP53'}) -- 创建节点
MATCH (g:Gene {name:'TP53'}) RETURN g -- 查询节点
MATCH (a)-[r]->(b) RETURN a,r,b LIMIT 10 -- 查看关系
MATCH p=(a)-[*1..3]->(b) RETURN p -- 1到3跳路径查询
MATCH (g:Gene)-[:ASSOCIATED_WITH]->(d:Disease) RETURN g,d -- 模式匹配
生信知识图谱数据库速查¶
| 数据库 | 内容 | 网址 |
|---|---|---|
| STRING | 蛋白质互作网络 | string-db.org |
| DisGeNET | 基因-疾病关联 | disgenet.org |
| DrugBank | 药物-靶点数据 | drugbank.com |
| Gene Ontology | 基因功能本体 | geneontology.org |
| KEGG | 代谢通路数据库 | kegg.jp |
| Reactome | 生物通路知识库 | reactome.org |
| BioGRID | 基因/蛋白质互作 | thebiogrid.org |
| UniProt | 蛋白质序列和功能 | uniprot.org |
12. 延伸资源¶
入门教程¶
- NetworkX 官方教程:networkx.org/documentation/stable/tutorial.html(Python 图分析入门,当前版本 3.6.1)
- Neo4j 官方文档:neo4j.com/docs/(Cypher 查询语言教程)
- Microsoft GraphRAG:github.com/microsoft/graphrag(LLM + 知识图谱的参考实现)
进阶学习¶
- 论文:"From Local to Global: A Graph RAG Approach to Query-Focused Summarization"(微软 GraphRAG 原始论文,arXiv:2404.16130)
- 知识图谱嵌入:TransE、RotatE、CompGCN 等模型的原始论文
- 图神经网络:"A Gentle Introduction to Graph Neural Networks"(Distill.pub)
生信专用资源¶
- Hetionet:一个整合了基因、疾病、药物、通路等 11 种实体的异构生物医学知识图谱(github.com/hetio/hetionet)
- PrimeKG:精准医学知识图谱,整合了 20 个生物医学数据库(Harvard)
- BioKG:生物医学知识图谱构建框架
与本知识库其他篇目的关系¶
- 50 篇(向量数据库):知识图谱做关系推理,向量数据库做相似度搜索,两者互补
- 02 篇(LangChain + RAG):GraphRAG 是 RAG 的升级版,建议先看 02 篇再看本篇
- 12 篇(单细胞分析 Scanpy):单细胞分析中的基因调控网络也可以用图来表示
- 18 篇(多组学整合):多组学整合可以用知识图谱把不同组学层次的数据串联起来