知识图谱基础

各位同学好,今天咱们聊聊知识图谱。坦白说,我最早接触这东西是在做药物分子关联分析的项目里,那时候数据乱得像一团麻,直到把知识图谱搭起来,才真正把结构理清了。

知识图谱,说白了就是用图的结构来组织知识。它把现实世界中的实体和它们之间的关系,变成一个可以查询、推理的网。

知识图谱的定义

我个人习惯把它分成三层来理解:

  • 数据层:最底层的原始数据,比如药物名称、基因序列、副作用描述。
  • 模式层:定义实体类型和关系类型,相当于数据库的“表结构”。
  • 实例层:具体的实体和关系,比如“阿司匹林”是一个药物,“布洛芬”也是一个药物,它们之间没有直接关系。

你想想看,很多做传统数据库的同事一开始觉得知识图谱就是另一个NoSQL。其实它最大的区别在于:知识图谱不仅存数据,还存数据之间的语义。嗯,这点很重要。

我的小经验:在药物KG项目中,模式层的设计最花时间。我曾因为把“药物-靶点”和“药物-疾病”的关系类型定义得太笼统,导致后期推理查出来的结果全是噪音。后来老老实实把关系细分成“inhibits_activity”、“binds_tightly”、“causes_adverse_effect”等类型,才好用。

三元组结构

知识图谱最基础的存储单元就是三元组(Triple)。格式很简单:(头实体, 关系, 尾实体)。举个例子:

(阿司匹林, 治疗, 头痛)
(布洛芬, 与药物相互作用, 华法林)
(华法林, 属于, 抗凝血药)

为什么会用三元组?因为它足够通用。任何知识都能拆成这样一条一条的陈述。我在项目中经常把三元组比作乐高积木,每一个小块都很简单,但拼起来能构建庞大的知识网络。

这里有一个坑:三元组的方向性。关系是有方向的,“阿司匹林治疗头痛”和“头痛被阿司匹林治疗”在有些系统中不等价。我以前踩过这个坑,图查询时写反了方向,结果查出来一堆无关结果。

存储方式

知识图谱的存储主要有两种路数:

存储方式 典型代表 适合场景
RDF 三元组存储 Apache Jena、Virtuoso 标准化的语义网场景,SPARQL 查询
图数据库 Neo4j、JanusGraph 大规模图遍历、节点/关系分析

我个人偏好图数据库,尤其是做药物KG这种需要频繁路径搜索的场景。Neo4j 的 Cypher 查询语言写起来非常直观。比如查“哪些药物和布洛芬共用时会有相互作用?”:

MATCH (d:Drug)-[:INTERACTS_WITH]->(b:Drug {name: '布洛芬'})
RETURN d.name

一行搞定。如果是 RDF,用 SPARQL 写起来会多几行,但遇到复杂的本体推理时,RDF 的 OWL 支持又很香。

避坑指南:我曾经在一个项目中混合使用两种存储,想着各取所长。结果数据同步搞得一塌糊涂,每周都要跑批对账。建议初期只选一种方案,做透了再考虑扩展。

知识图谱在药物领域的典型结构

咱们的课程重点在药物KG,我画了一张图帮大家直观理解核心结构。

药物知识图谱核心结构 药物 靶点 疾病 作用于 与……相关 副作用 基因 通路 引起 编码 失调 参与 说明 药物KG将药物、靶点、疾病、基因、通路等实体
通过语义关系连接,形成可推理的知识网络

图里展示了药物KG中最常见的几种实体和关系。实际项目还会有临床试验、文献、化学结构等节点,关系类型也会更细。但记住一点:所有知识图谱的骨架都是三元组,这个底子打好了,后面学RotatE和GCN就容易多了。

最后说个题外话。我刚开始带团队做药物KG时,有人觉得直接用表格存不就行了?非要用什么三元组。后来我们跑链路预测和药物重定位任务时,才知道图结构有多香——你想想,一个药物和另一个药物共享相同的靶点,这种“共同靶点”关系在表里得写一堆外键,在图里一条边就解决了。

好了,这一章的知识点就这么多。记住定义、理解三元组、知道两种主流存储方式,应付后面的课程就够了。