
摘要:贝叶斯网络是带结构的概率图模型,用有向无环图(DAG)表示变量间的因果依赖,既能建模复杂关系,又能进行精确概率推理!
如果你在搜索:
那么,这篇文章就是为你写的——从拓扑结构到联合概率分解,一步不跳。
用有向无环图(DAG)显式建模变量间的条件依赖关系。
✅ 优势:
贝叶斯网络的核心公式:

即:联合概率 = 所有节点的条件概率之积
我们构建如下贝叶斯网络:
感冒 (G) ──→ 发烧 (F)
│
└──────→ 咳嗽 (C)是(1) / 否(0)G | P(G) |
|---|---|
0 | 0.9 |
1 | 0.1 |
| G | F | P(F|G) | |-----|-----|--------| | 0 | 0 | 0.95 | | 0 | 1 | 0.05 | | 1 | 0 | 0.2 | | 1 | 1 | 0.8 |
| G | C | P(C|G) | |-----|-----|--------| | 0 | 0 | 0.9 | | 0 | 1 | 0.1 | | 1 | 0 | 0.3 | | 1 | 1 | 0.7 |
目标:已知患者发烧且咳嗽(F=1, C=1),求患感冒的概率 (P(G=1 | F=1, C=1))
根据网络结构

我们需要计算:

P(0,1,1)=P(G=0)⋅P(F=1∣G=0)⋅P(C=1∣G=0)=0.9×0.05×0.1=0.0045
P(1,1,1) =0.1×0.8×0.7=0.056
→ 归一化常数 = (0.0045 + 0.056 = 0.0605)

✅ 结论:在同时发烧和咳嗽的情况下,患感冒的概率高达 92.6%!
💡 对比朴素贝叶斯:若强行假设 F 和 C 独立(给定 G),结果相同(本例中恰好结构匹配)。但若网络更复杂(如 F → C),朴素贝叶斯将失效。
⚠️ 贝叶斯网络需专用库(如
pgmpy),scikit-learn 不支持
pip install pgmpyfrom pgmpy.models import BayesianNetwork
from pgmpy.factors.discrete import TabularCPD
from pgmpy.inference import VariableElimination
# 定义网络结构
model = BayesianNetwork()
# 定义 CPD
cpd_g = TabularCPD(variable='G', variable_card=2,
values=[[0.9], [0.1]], # [P(G=0), P(G=1)]
state_names={'G': [0, 1]})
cpd_f = TabularCPD(variable='F', variable_card=2,
values=[[0.95, 0.2], # P(F=0 | G=0), P(F=0 | G=1)
[0.05, 0.8]], # P(F=1 | G=0), P(F=1 | G=1)
evidence=['G'],
evidence_card=[2],
state_names={'F': [0, 1], 'G': [0, 1]})
cpd_c = TabularCPD(variable='C', variable_card=2,
values=[[0.9, 0.3],
[0.1, 0.7]],
evidence=['G'],
evidence_card=[2],
state_names={'C': [0, 1], 'G': [0, 1]})
# 添加 CPD 到模型
model.add_cpds(cpd_g, cpd_f, cpd_c)
# 检查模型是否有效
assert model.check_model()
# 推理
infer = VariableElimination(model)
result = infer.query(variables=['G'], evidence={'F': 1, 'C': 1})
print("P(G=1 | F=1, C=1) =", result.values[1]) # 输出: ~0.9256Java 无成熟贝叶斯网络库,以下为简化版(仅支持本例结构)
import java.util.*;
public class BayesianNetwork {
// 先验 P(G)
private static final double P_G1 = 0.1;
private static final double P_G0 = 0.9;
// 条件概率 P(F|G)
private static double P_F1_given_G(int g) {
return (g == 1) ? 0.8 : 0.05;
}
// 条件概率 P(C|G)
private static double P_C1_given_G(int g) {
return (g == 1) ? 0.7 : 0.1;
}
public static double inferG1GivenF1C1() {
double joint_G0 = P_G0 * P_F1_given_G(0) * P_C1_given_G(0); // 0.0045
double joint_G1 = P_G1 * P_F1_given_G(1) * P_C1_given_G(1); // 0.056
double evidence = joint_G0 + joint_G1; // 0.0605
return joint_G1 / evidence;
}
public static void main(String[] args) {
double prob = inferG1GivenF1C1();
System.out.printf("P(G=1 | F=1, C=1) = %.4f\n", prob); // 输出: 0.9256
}
}💡 通用BN推理需实现:
优点 | 缺点 |
|---|---|
✅ 显式建模因果/依赖关系 | ❌ 结构学习困难(NP-hard) |
✅ 支持双向推理(诊断+预测) | ❌ 精确推理在大型网络中计算昂贵 |
✅ 可融合专家知识 | ❌ CPT 参数需大量数据或专家设定 |
✅ 概率输出可解释性强 | ❌ 连续变量需高斯假设或离散化 |
算法 | 依赖假设 | 数据类型 | 可解释性 | 适用场景 |
|---|---|---|---|---|
朴素贝叶斯 | 所有特征独立 | 离散/连续 | 高 | 文本分类、快速基线 |
AODE | 允许一阶依赖 | 离散 | 中 | 中小离散数据集 |
贝叶斯网络 | 任意DAG结构 | 离散/连续 | 极高 | 因果推理、专家系统 |
💡 选择建议:
贝叶斯网络将概率论与图论完美结合,不仅是一个分类器,更是一个推理引擎。它让我们能像医生一样思考:“如果这个症状出现,最可能的原因是什么?”
记住:在AI时代,理解因果比预测相关更重要。
现在,你已经能:
相关链接
无论你是想写代码调用 API 的开发者,设计 AI 产品的 PM,评估技术路线的管理者,还是单纯好奇智能本质的思考者,这里都有值得你驻足的内容。 不追 hype,只讲逻辑;不谈玄学,专注可复现的认知。 让我们一起,在这场百年一遇的智能革命中,看得更清,走得更稳 https://cloud.tencent.com/developer/column/107314
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。