贝叶斯网络入门教程(原理介绍+python代码实现)

这篇具有很好参考价值的文章主要介绍了贝叶斯网络入门教程(原理介绍+python代码实现)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

贝叶斯网络原理

贝叶斯网络(Bayesian Network)是一种去除了条件概率独立性的概率图模型,其结构为有向无环图(direct acyclic graph,DAG), 图中每个节点代表一个随机变量,每个节点有对应的概率分布表,有向边表示各节点之间的依赖关系。

局部马尔科夫性

贝叶斯网络的一个性质是局部马尔可夫性。

Assumption 1.1 (Local Markov Assumption) 给定一个节点 X X X在有向无环图中的父节点,该节点独立于其所有非后继节点。

对于相互独立的多个变量的联合概率分布,有:
P ( x 1 , x 2 , . . . , x n ) = p ( x 1 ) p ( x 2 ∣ x 1 ) p ( x 3 ∣ x 1 , x 2 ) . . . p ( x n ∣ x n − 1 . . . x 1 ) ( 1.1 ) P(x_1,x_2,...,x_n)=p(x_1)p(x_2|x_1)p(x_3|x_1,x_2)...p(x_n|x_{n-1}...x_1) \qquad(1.1) P(x1,x2,...,xn)=p(x1)p(x2x1)p(x3x1,x2)...p(xnxn1...x1)(1.1)
若变量具有局部马尔可夫性,则联合概率分布可简化为:
P ( x 1 , x 2 , . . . , x n ) = P ( x i ∣ ∏ i = 1 n P a r e n t s ( x i ) ) ( 1.2 ) P(x_1,x_2,...,x_n)=P(x_i|\prod_{i=1}^nParents(x_i)) \qquad(1.2) P(x1,x2,...,xn)=P(xii=1nParents(xi))(1.2)

案例实战

基于pgmpy的python包实现一个用贝叶斯网络进行推理的例子。
安装:

pip install pgmpy

以学生获得推荐信的质量为例,来构造贝叶斯网络。各节点构成的有向无环图和对应的概率表如图所示。从图中可看出推荐信(letter)的质量受到学生成绩(grade)的直接影响,而考试难度(diff)和智力(intel)直接影响学生的成绩。智力还影响SAT的分数。
贝叶斯网络入门教程(原理介绍+python代码实现)
使用贝叶斯网络推理一个天赋较高的学生在考试较难的情况下获得推荐信的质量的概率分布,步骤如下。
step1: 定义贝叶斯网络结构。

from pgmpy.models import BayesianNetwork
letter_bn=BayesianNetwork([
    ('D','G'),('I','G'),('I','S'),('G','L') # 指向关系 D->I
])

step2: 构建各节点的条件概率分布。

from pgmpy.factors.discrete import TabularCPD
d_cpd=TabularCPD(variable='D',variable_card=2,values=[[0.6],[0.4]])
# 变量名,变量取值个数,对应概率
i_cpd=TabularCPD(variable='I',variable_card=2,values=[[0.7],[0.3]])
g_cpd=TabularCPD(variable='G',variable_card=3,values=[[0.3,0.05,0.9,0.5],[0.4,0.25,0.08,0.3],[0.3,0.7,0.02,0.2]],
 # 行数等于变量取值,列数等于依赖变量总取值数(3,4)
evidence=['I','D'],evidence_card=[2,2]) 
# 变量名,变量取值个数,对应概率,依赖变量名,依赖变量取值
s_cpd=TabularCPD(variable='S',variable_card=2,values=[[0.95,0.2],[0.05,0.8]],
                 evidence=['I'],evidence_card=[2])
l_cpd=TabularCPD(variable='L',variable_card=2,values=[[0.1,0.4,0.99],[0.9,0.6,0.01]],
                 evidence=['G'],evidence_card=[3]) # evidence_card必须是列表

注意:这里条件概率表的行数等于变量取值,列数等于依赖变量总取值组合数;evidence_card必须是列表。
step3: 添加概率表到贝叶斯网络,检查模型,并输出。

letter_bn.add_cpds(d_cpd,i_cpd,g_cpd,s_cpd,l_cpd)
letter_bn.check_model() # 检查构建的模型是否合理
letter_bn.get_cpds() # 网络中条件概率依赖关系

step4: 利用构建的贝叶斯网络进行具体的推理。这里推断一个天赋较高的学生在考试较难的情况下获得推荐信的质量的概率分布。

from pgmpy.inference import VariableElimination
letter_infer=VariableElimination(letter_bn) # 变量消除
prob_I=letter_infer.query(variables=['L'],evidence={'I':1,'D':1})
print(f"prob_I:{prob_I}")

输出结果如下,可看到得到劣质推荐信的概率为0.368,得到优质推荐信的概率为0.632。

prob_I:
+------+----------+
| L    |   phi(L) |
+======+==========+
| L(0) |   0.3680 |
+------+----------+
| L(1) |   0.6320 |
+------+----------+

pgmpy源码剖析

  • BayesianNetwork
    pgmpy中BayesianNetwork类继承于DAG类。DAG类是基于network的有向图模块构建的,该类返回一个有向无环图。
    贝叶斯网络入门教程(原理介绍+python代码实现)

一个简要的贝叶斯网络的伪代码如下:

class BayesianNetwork(DAG):
    def __init__(self, ebunch=None, latents=set()):
        """
        构造一个贝叶斯网络模型;
        模型存储节点以及带有条件概率表和其他属性的边;
        边为有向边;
        """
        super(BayesianNetwork, self).__init__(ebunch=ebunch, latents=latents)
        self.cpds = []
        self.cardinalities = defaultdict(int)

    def add_cpds(self, *cpds):
        """
        # 添加条件概率分布到贝叶斯网络中
        cpds  :  list, set, tuple (array-like), List of CPDs which will be associated with the model
        """
        for cpd in cpds:
            if not isinstance(cpd, (TabularCPD, ContinuousFactor)):
                raise ValueError("Only TabularCPD or ContinuousFactor can be added.")

            if set(cpd.scope()) - set(cpd.scope()).intersection(set(self.nodes())):
                raise ValueError("CPD defined on variable not in the model", cpd)

            for prev_cpd_index in range(len(self.cpds)):
                if self.cpds[prev_cpd_index].variable == cpd.variable:
                    logging.info(f"Replacing existing CPD for {cpd.variable}")
                    self.cpds[prev_cpd_index] = cpd
                    break
            else:
                self.cpds.append(cpd)

    def get_cardinality(self, node=None):
        """
        返回节点(随机变量)的取值个数
        """
        if node is not None:
            return self.get_cpds(node).cardinality[0]
        else:
            cardinalities = defaultdict(int)
            for cpd in self.cpds:
                cardinalities[cpd.variable] = cpd.cardinality[0]
            return cardinalities

构造一个贝叶斯网络示例:

from pgmpy.models import BayesianNetwork
from pgmpy.factors.discrete import TabularCPD
student = BayesianNetwork([('diff', 'grade'), ('intel', 'grade')]) # 节点指向关系 diff->grade,intel->grade
cpd_diff = TabularCPD('diff', 2, [[0.6], [0.4]])
cpd_intel = TabularCPD('intel', 2, [[0.7], [0.3]])
cpd_grade = TabularCPD('grade', 2, [[0.1, 0.9, 0.2, 0.7],
 [0.9, 0.1, 0.8, 0.3]],['intel', 'diff'], [2, 2])
student.add_cpds(cpd_diff,cpd_intel,cpd_grade)
student.get_cardinality() # defaultdict(int, {'diff': 2, 'intel': 2, 'grade': 2})
print(f"grade节点的取值个数:{student.get_cardinality('grade')}") # grade节点的取值个数:2
  • TabularCPD
    TabularCPD类定义了各种条件概率分布表(conditional probability distribution table)。
    简要代码如下:
    贝叶斯网络入门教程(原理介绍+python代码实现)

构建一个条件概率表示例:

cpd = TabularCPD(variable='grade', # 随机变量名
                 variable_card=3, # 随机变量的取值个数
                 values=[[0.1,0.1,0.1,0.1,0.1,0.1], # 该随机变量的概率表
                        [0.1,0.1,0.1,0.1,0.1,0.1],
                        [0.8,0.8,0.8,0.8,0.8,0.8]],
                evidence=['diff', 'intel'], # 该随机变量的依赖变量
                 evidence_card=[2,3]) # 依赖变量的取值个数
print(cpd)

贝叶斯网络入门教程(原理介绍+python代码实现)

参考资料

  1. https://pgmpy.org/detailed_notebooks/2.%20Bayesian%20Networks.html
  2. Brady Neal. 2020.Introduction to Causal Inference from a machine learning perspective[M], chapter 3, p28-30.
  3. Conrady S , Jouffe L . Bayesian Networks & BayesiaLab - A Practical Introduction for Researchers[M]. 2015.
  4. Pearl J . Causality: models, reasoning, and inference[M]. Cambridge University Press, 2000.
  5. A Bayesian network approach for population synthesis. https://www.sciencedirect.com/science/article/pii/S0968090X15003599

强烈推荐阅读贝叶斯网络的发明者朱迪亚·珀尔(Judea Pearl)的书Causality: models, reasoning, and inference,了解更多细节。文章来源地址https://www.toymoban.com/news/detail-414421.html

到了这里,关于贝叶斯网络入门教程(原理介绍+python代码实现)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【业务工具】MobaXterm入门介绍和简单教程

    本文主要整理自: zhihu:MobaXterm详细使用教程系列一 (作者Gang Tang) 实习用到MobaXterm软件,自己入门扫盲一下。 本篇以了解基础概念和大概使用为主。 MobaXterm是一个SSH客户端,SSH客户端的作用是帮助我们在windows下面连接并操作linux服务器。 SSH是一个远程登录的协议。 SSH 为

    2024年02月06日
    浏览(49)
  • CANOE 入门使用教程【三】------发送报文介绍

    前面已经介绍了CANOE的新建工程,trace窗口的介绍,工作中也会经常要发送报文,本文介绍一下如何发送报文 在Simulation Setup窗口,右键选择Insert CAN Interactive Generators 生成CAN IG模块后 双击打开CAN IG模块,新增要发送的报文 以新增CAN frame为例,ID,改成你要发送的ID,channel选择

    2024年02月02日
    浏览(42)
  • WPF真入门教程23--MVVM简单介绍

            在WPF开发中,经典的编程模式是MVVM,是为WPF量身定做的模式,该模式充分利用了WPF的数据绑定机制,最大限度地降低了Xmal文件和CS文件的耦合度,也就是UI显示和逻辑代码的耦合度,如需要更换界面时,逻辑代码修改很少,甚至不用修改。与WinForm开发相比,我们一般

    2024年02月03日
    浏览(40)
  • Stable Diffusion的入门介绍和使用教程

    Stable Diffusion是一个文本到图像的潜在扩散模型,由CompVis、Stability AI和LAION的研究人员和工程师创建。它使用来自LAION-5B数据库子集的512x512图像进行训练。使用这个模型,可以生成包括人脸在内的任何图像,因为有开源的预训练模型,所以我们也可以在自己的机器上运行它,如

    2024年02月02日
    浏览(41)
  • 《JavaCV从入门到实战教程合集》介绍和目录

    《JavaCV音视频合集》是《JavaCV入门指南》、《JavaCV开发详解》、《JavaCV进阶之FFmpeg》和2022年《JavaCV音视频开发宝典》四合一汇总合集,完整包含《JavaCV入门指南》、《JavaCV开发详解》、《JavaCV进阶之FFmpeg》和《JavaCV音视频开发宝典》系列所有付费内容。 《JavaCV入门指南》 《

    2023年04月11日
    浏览(37)
  • Streamlit库入门级教程(一)——基本介绍和使用方式

    最近做比赛了解到了Streamlit这个库,花了几天时间浅浅入门了一下,官网虽有完整的API文档等教程,但是纯英文版的,阅读起来有些许费力,在这里想以自己的逻辑用中文简单复刻一些入门级内容,方便 小白 使用(大佬看见轻喷)~ Streamlit库官方地址:https://streamlit.io/ API文

    2023年04月20日
    浏览(50)
  • 网络安全入门教程(非常详细)从零基础入门到精通

    1.入行网络安全这是一条坚持的道路,三分钟的热情可以放弃往下看了。 2.多练多想,不要离开了教程什么都不会了,最好看完教程自己独立完成技术方面的开发。 3.有时多百度,我们往往都遇不到好心的大神,谁会无聊天天给你做解答。 4.遇到实在搞不懂的,可以先放放,

    2024年01月18日
    浏览(50)
  • 网络安全入门教程(非常详细)从零基础入门到精通!

    网络安全是一个庞大而不断发展的领域,它包含多个专业领域,如网络防御、网络攻击、数据加密等。介绍网络安全的基本概念、技术和工具,逐步深入,帮助您成为一名合格的网络安全从业人员。 1.计算机基础知识 了解了计算机的硬件、软件、操作系统和网络结构等基础知

    2024年04月13日
    浏览(60)
  • 【GoLang入门教程】Go语言几种标准库介绍(六)

    前言 上一篇,我们介绍了image、IO、math三个库,这篇我们继续介绍剩下的库 几种库 Net库 (网络库,支持 Socket、HTTP、邮件、RPC、SMTP 等) 在 Go 语言的标准库中, net 包提供了对网络操作的支持,包括基本的网络协议、Socket 编程、HTTP 客户端和服务器等。 net 包包含多个子包,其

    2024年02月02日
    浏览(56)
  • 【GoLang入门教程】Go语言几种标准库介绍(七)

    前言 上一篇,我们介绍了Net、OS、path三个库,这篇我们继续介绍剩下的库 几种库 plugin库 (Go 1.7 加入的插件系统。支持将代码编译为插件,按需加载) 在 Go 语言的标准库中, plugin 包提供了对 Go 插件的支持。 插件是一种在运行时加载并与主程序交互的机制,允许程序在不重新

    2024年01月16日
    浏览(81)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包