一个 DuckDB 数据库,同时跑 SQL、图查询和贝叶斯推理
我一直想找个办法,把概率推理塞进数据分析的流水线里。
但现实是:数据工程师用 SQL 查表,知识图谱团队用 Neo4j/Cypher 看关系,做贝叶斯的人用 OpenMarkov 或 pgmpy 跑概率。三套工具,三份数据,格式来回转。
Sixing Huang 用一个小项目把这事搞定了,叫 DuckBay。
核心思路很简单——用 DuckDB 作为唯一存储引擎,同一份数据可以当知识图谱查,也可以当贝叶斯网络做推理。
● ● ●
从三个工具到一个文件
DuckBay 的前身是作者之前的「贝叶斯知识图谱」原型。那个版本用 Google Sheets 存数据、Neo4j 做可视化、OpenMarkov 做推理。
听起来功能齐备,但实际用起来每一步都在做格式转换:Sheets→TSV→Neo4j,Sheets→XML→OpenMarkov。改一个节点的概率值,要手动同步到三处。
DuckBay 把这一切压缩到一个 DuckDB 文件里。四张表搞定:
node— 变量节点(名称、状态列表、分类标签、扩展属性)relation— 有向边(源节点、目标节点、排序位置、标签)cpt— 条件概率表(节点ID、列索引、行索引、概率值)label— 标签颜色映射
同一个 .duckdb 文件,你既可以用 SQL 查表:
SELECT n.name, c.state_index, c.probability FROM node n JOIN cpt c ON n.id = c.node_id WHERE n.name = 'Disease';
也可以用 Cypher 做图遍历(通过 DuckPGQ 扩展):
MATCH (s:Symptom)-[:CAUSES]->(d:Disease) WHERE s.name = 'Fever' RETURN d.name, d.probability
还可以直接调 pgmpy 的 Variable Elimination 做精确推理——输入证据,输出每个变量的后验概率。
格式转换这一步,彻底消失了。
● ● ●
硬币的两面
DuckBay 把这个设计叫做「硬币和它的两面」:
硬币是 DuckDB,一面是知识图谱(图查询、可视化),另一面是贝叶斯网络(概率推理、因果推断)。
┌──────────────┐
│ DuckDB │ ← 唯一数据源
│ 4 张核心表 │
└───┬──────┬───┘
│ │
┌────────┘ └────────┐
▼ ▼
知识图谱视图 贝叶斯网络视图
· SQL 聚合查询 · Variable Elimination
· Cypher 图遍历 · 前向后向推理
· PGQ 路径查找 · 因果链分析
· 图谱可视化 · 边际概率可视化
这套架构的优点不是功能——它只是一个 FastAPI 服务 + vis.js 前端。真正的价值在于:同一份数据不需要维护多个副本。你改一次 CPT 值,SQL 查询和贝叶斯推理同时生效。
DuckBay 架构
● ● ●
推理链路
推理引擎用的是 pgmpy,一个 Python 概率图模型库。DuckBay 目前只用到它的 VariableElimination(精确推理)。
流程很直接:
- 01从 DuckDB 加载 node/relation/cpt 表 → 组装节点字典
- 02构建
DiscreteBayesianNetwork→ 添加边和条件概率分布 - 03CPT 自动归一化(零列变均匀分布)
- 04
VariableElimination.query(variables, evidence)→ 返回每个变量的边际概率
支持的三种推理:
- 诊断推理:给定症状,反推病因概率 — P(病因 | 症状)
- 预测推理:给定原因,预测结果概率 — P(结果 | 原因)
- Intercausal 推理:多个证据互相竞争/增强
比如在文章示例的 COVID 改编版 Asia 网络模型中,你可以设定「去过疫区=Yes」和「检测阳性=Yes」,让系统自动算出「COVID 感染」的后验概率从先验的 1% 飙升到 82%。
● ● ●
一个被低估的细节:DuckDB 的多模型能力
DuckBay 值得关注的不只是贝叶斯推理本身,而是它展示了 DuckDB 作为「多模型数据库」的潜力。
传统上 DuckDB 被看作列式 OLAP 引擎——查 CSV/Parquet 快、做聚合猛。但 DuckBay 用了 DuckDB 的三个维度:
- 01SQL 分析 — 聚合、过滤、JOIN,查 CPT 概率表
- 02图查询 — DuckPGQ 扩展,支持 SQL/PGQ 标准的 Cypher 语法
- 03数组/JSON 类型 —
VARCHAR[]存状态列表,JSON 存扩展属性
一个嵌入式单文件数据库,同时支持关系、图、文档三种数据模型。不需要部署 Neo4j 集群,不需要搞数据同步。
这意味着什么?如果你的数据流水线本来就用 DuckDB,那加上图查询和概率推理不需要换数据库——只需要加两张表和一个推理函数。
● ● ●
BIF 互操作:几百个现成模型随便导
DuckBay 支持导入 BIF(Bayesian Interchange Format)文件。BIF 是贝叶斯网络的标准交换格式,bnlearn 这类工具库里有数百个现成的网络模型——从医疗诊断(Alarm、Hepar II)到风险评估(Insurance、Munin)。
一行命令:
python import_bif.py bif/hepar2.bif hepar2
70 个节点的肝病诊断网络就直接进 DuckDB 了。然后你可以在 Web 编辑器里修改、推理、导出。
导出方向也覆盖了主流图数据库:Neo4j(按 label 分组导出 CSV)和 PuppyGraph(schema.json)。还能同步到 MotherDuck/DuckLake 做云端访问。
● ● ●
局限
这个小项目只有 24 个 commit,显然不是生产级产品。几个明显的局限:
- 01只能做离散变量 — 不支持连续概率分布(虽然 pgmpy 本身支持 LinearGaussianBN)
- 02精确推理的复杂度瓶颈 — VE 在大网络上是指数级的,没有内置近似推理
- 03网络结构必须手动定义 — 没有从数据自动学习结构的能力(pgmpy 有 PC 算法和 GES,但 DuckBay 没接)
- 04单用户 — 无认证、无多租户
- 05DuckPGQ 版本敏感 — DuckPGQ 1.2.1 有 breaking change,目前只能跑在 1.1.3
● ● ●
为什么值得关注
DuckBay 不是一个「大而全」的产品,它是一个精准的实验——验证了一个假设:DuckDB 可以同时做 SQL OLAP、图遍历和概率推理的底层存储,且不需要任何数据同步。
24 个 commit 做到这个完整度(BIF 导入、Neo4j 导出、PuppyGraph 导出、MotherDuck 同步、前端编辑器、推理面板),说明这个假设是成立的。
对做 DuckDB 数据流水线的人来说,这意味着:想加图查询?想跑概率推理?不用再引入 Neo4j 或者 Spark。你的 DuckDB 文件本来就能干这些事。
GitHub: dgg32/gemini_bayesian
原文: DuckBay: The Bayesian Knowledge Graph App