alitrack

一个 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 架构

DuckBay 架构

● ● ●

推理链路

推理引擎用的是 pgmpy,一个 Python 概率图模型库。DuckBay 目前只用到它的 VariableElimination(精确推理)。

流程很直接:

  1. 01从 DuckDB 加载 node/relation/cpt 表 → 组装节点字典
  2. 02构建 DiscreteBayesianNetwork → 添加边和条件概率分布
  3. 03CPT 自动归一化(零列变均匀分布)
  4. 04VariableElimination.query(variables, evidence) → 返回每个变量的边际概率

支持的三种推理:

  • 诊断推理:给定症状,反推病因概率 — P(病因 | 症状)
  • 预测推理:给定原因,预测结果概率 — P(结果 | 原因)
  • Intercausal 推理:多个证据互相竞争/增强

比如在文章示例的 COVID 改编版 Asia 网络模型中,你可以设定「去过疫区=Yes」和「检测阳性=Yes」,让系统自动算出「COVID 感染」的后验概率从先验的 1% 飙升到 82%。

● ● ●

一个被低估的细节:DuckDB 的多模型能力

DuckBay 值得关注的不只是贝叶斯推理本身,而是它展示了 DuckDB 作为「多模型数据库」的潜力。

传统上 DuckDB 被看作列式 OLAP 引擎——查 CSV/Parquet 快、做聚合猛。但 DuckBay 用了 DuckDB 的三个维度:

  1. 01SQL 分析 — 聚合、过滤、JOIN,查 CPT 概率表
  2. 02图查询 — DuckPGQ 扩展,支持 SQL/PGQ 标准的 Cypher 语法
  3. 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,显然不是生产级产品。几个明显的局限:

  1. 01只能做离散变量 — 不支持连续概率分布(虽然 pgmpy 本身支持 LinearGaussianBN)
  2. 02精确推理的复杂度瓶颈 — VE 在大网络上是指数级的,没有内置近似推理
  3. 03网络结构必须手动定义 — 没有从数据自动学习结构的能力(pgmpy 有 PC 算法和 GES,但 DuckBay 没接)
  4. 04单用户 — 无认证、无多租户
  5. 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