【数据挖掘】贝叶斯网络理论及Python实现

article/2025/10/2 17:48:51

1.理论知识

1.1贝叶斯网络概述

  贝叶斯网络(Bayesian Network,BN)作为一种概率图模型(Probabilistic Graphical Model,PGD),可以通过有向无环图(Directed Acyclic Graph,DAG)来表现。因为概率图模型是用图来表示变量概率依赖关系的模型,结合概率论与图论的知识,利用图来表示与模型有关的变量的联合概率分布。在处理实际问题时,如果我们希望在数据中挖掘隐含的知识,可以通过概率图模型构建一幅图的方式实现,具体实现就是用观测结点表示观测到的数据,用隐含结点表示潜在的知识,用边来描述知识与数据的相互关系,最后基于这样的关系图获得一个概率分布。概率图中的节点分为隐含节点和观测节点,边分为有向边和无向边。从概率论的角度,节点对应于随机变量,边对应于随机变量的依赖或相关关系,其中有向边表示单向的依赖或者说存在因果关系无向边表示相互依赖关系
  贝叶斯网络是一种模拟人类推理过程中因果关系的不确定性处理模型,它是一个有向无环图,它的节点表示的是一些随机变量,这些随机变量有些可以观测到的,有些无法观测到的。无环表示在信息流动的过程中有一个确定的方向的。当一件事物发生的时候,另一件事情更容易发生,这时候就用概率来表达,而且这种概率通常表达的是因果关系。
  贝叶斯网络是一种模拟人类推理过程中因果关系的不确定性处理模型,也是一些变量的联合概率分布的图形表示。通常包含两个部分,一个是贝叶斯网络结构图,它是一个有向无环图(DAG),其中图中的每个节点代表相应的变量,节点之间的连接关系代表了贝叶斯网络的条件独立语义。另一部分,就是节点和节点之间的条件概率表(CPT),也就是一系列的概率值。如果一个贝叶斯网络提供了足够的条件概率值,足以计算任何给定的联合概率,我们就称,它是可计算的,即可推理的。
  什么是贝叶斯推断?使用贝叶斯方法处理不确定性,需要利用贝叶斯定理将先验分布更新至后验分布中,这无疑是最流行的方法之一。但还存在其他非贝叶斯方法,例如集中不等式就是非贝叶斯方法,它们允许计算置信区间和不确定性集合。

1.2贝叶斯网络实例

  首先从一个具体的实例(医疗诊断的例子)来说明贝叶斯网络的构造。
  假设:
  随机变量S(smoker):该患者是一个吸烟者
  随机变量C(coal Miner):该患者是一个煤矿矿井工人
  随机变量L(ung Cancer):他患了肺癌
  随机变量E(mphysema):他患了肺气肿
  变量S对变量L和变量E有因果影响,而变量C对变量E也有因果影响。
  变量之间的关系可以描绘成如下图所示的因果关系网。所以贝叶斯网络有时也叫因果关系网,因为可以将连接节点的弧表示直接的因果关系。
在这里插入图片描述

根据上述图可知贝叶斯网络的两个要素:一个是贝叶斯网络的结构,即各节点的继承关系,另一是是条件概率表(CPT)。如果要保证一个贝叶斯网络可计算,则这两个条件缺一不可。

如何用贝叶斯网络对该问题进行建模表示

  1. 如何定义节点?
  2. 如何定义节点之间的概率依赖关系?
  3. 如何表示联合概率分布?

1.3贝叶斯网络定义

  贝叶斯网络是一个有向无环图(Directed Acyclic Graph, DAG),由代表变量节点及连接这些节点有向边构成。其中节点代表随机变量,节点间的有向边代表了节点间的互相关系(由父节点指向其子节点),用条件概率表达变量间依赖关系,没有父节点的用先验概率进行信息表达。
令 G 为定义在 { X 1 , X 2 , . . . , X n } \{X_{1},X_{2},...,X_{n}\} {X1,X2,...,Xn}上的一个贝叶斯网络,其联合概率分布可以表示为各个 节点的条件概率分布的乘积 :
p ( X ) = ∏ i p i ( X i ∣ Par ⁡ G ( X i ) ) p(X)=\prod_{i} p_{i}\left(X_{i} \mid \operatorname{Par}_{G}\left(X_{i}\right)\right) p(X)=ipi(XiParG(Xi))

1.4贝叶斯网络结构

  贝叶斯网络随机变量的连接方式主要有顺连、分连、汇连这三种连接形式,具体如下:
1.顺连
  如图 a a a所示,当 z z z未知时,变量 x x x的变化会影响z的置信度的变化,从而间接影响 y y y的置信度,所以此时x间接影响 y y y x x x y y y不独立。当变量 z z z的置信度确定时, x x x就不能影响 z z z,从而不能影响 y y y,此时 x x x y y y独立,因为此时 x x x y y y的通道被阻断了。
2.分连
  如图 b b b所示,分连代表一个原因导致多个结果,当变量 z z z已知时,变量 x x x y y y之间就不能相互影响,是独立的,而当变量 z z z未知时, z z z可以在变量 x x x y y y之间传递信息,从而使变量 x x x y y y相互影响从而不独立。
3.汇连
  汇连与分连恰好相反,代表多个原因导致一个结果,并且当变量z已知时,变量 x x x的置信度的提高会导致变量 y y y的置信度的降低,从而 x x x和y之间会相互影响所以是不独立的。而当 z z z未知时,变量 x x x y y y之间置信度互不影响,他们之间是独立的。
在这里插入图片描述

有关概念:
1.条件独立性:在贝叶斯网络中,如果两个节点是直接连接的,它们肯定是非条件独立的,是直接因果关系。
2.局部马尔可夫性质:对一个更一般的贝叶斯网络,其局部马尔可夫性质为:每个随机变量在给定父节点的情况下,条件独立于它的非后代节点。

2贝叶斯网络python实现

案例1:诊断癌症贝叶斯网络
在这里插入图片描述
提供如下数据信息:
美国有30%的人吸烟.
每10万人中就就有70人患有肺癌.
每10万人中就就有10人患有肺结核.
每10万人中就就有800人患有支气管炎.
10%人存在呼吸困难症状, 大部分人是哮喘、支气管炎和其他非肺结核、非肺癌性疾病引起.
在这里插入图片描述
代码实现如下:
基于python的pgmpy库构建贝叶斯网络,其步骤是先建立网络结构, 然后填入相关参数。
1.针对已知结构及参数,先采用BayesianModel构造贝叶斯网结构

#构建网络
from pgmpy.models import BayesianModel
cancer_model = BayesianModel([('Pollution', 'Cancer'),('Smoker', 'Cancer'),('Cancer', 'Xray'),('Cancer', 'Dyspnoea')])

这个贝叶斯网络中有五个节点: Pollution, Cancer, Smoker, Xray, Dyspnoea.

  • (‘Pollution’, ‘Cancer’): 一条有向边, 从 Pollution 指向 Cancer, 表示环境污染有可能导致癌症.
  • (‘Smoker’, ‘Cancer’): 吸烟有可能导致癌症.
  • (‘Cancer’, ‘Xray’): 得癌症的人可能会去照X射线.
  • (‘Cancer’, ‘Dyspnoea’): 得癌症的人可能会呼吸困难.

2.通过TabularCPD构造条件概率分布CPD(condition probability distribution)表格,最后将CPD数据添加到贝叶斯网络结构中,完成贝叶斯网络的构造。

#设置参数
from pgmpy.factors.discrete import TabularCPD
cpd_poll = TabularCPD(variable='Pollution', variable_card=2,values=[[0.9], [0.1]])
cpd_smoke = TabularCPD(variable='Smoker', variable_card=2,values=[[0.3], [0.7]])
cpd_cancer = TabularCPD(variable='Cancer', variable_card=2,values=[[0.03, 0.05, 0.001, 0.02],[0.97, 0.95, 0.999, 0.98]],evidence=['Smoker', 'Pollution'],evidence_card=[2, 2])
cpd_xray = TabularCPD(variable='Xray', variable_card=2,values=[[0.9, 0.2], [0.1, 0.8]],evidence=['Cancer'], evidence_card=[2])
cpd_dysp = TabularCPD(variable='Dyspnoea', variable_card=2,values=[[0.65, 0.3], [0.35, 0.7]],evidence=['Cancer'], evidence_card=[2])   
cancer_model.add_cpds(cpd_poll, cpd_smoke, cpd_cancer, cpd_xray, cpd_dysp)

这部分代码主要是建立一些概率表, 然后往表里面填入了一些参数.

  • Pollution: 有两种概率, 分别是 0.9 和 0.1.
  • Smoker: 有两种概率, 分别是 0.3 和 0.7. (意思是在一个人群里, 有 30% 的人吸烟, 有 70% 的人不吸烟)
  • Cancer: envidence 表示有 Smoker 和 Pollution 两个节点指向 Cancer 节点;

3.验证模型数据的正确性

#测试网络结构是否正确
print(cancer_model.check_model())

4.在构建了贝叶斯网之后, 我们使用贝叶斯网来进行推理. 推理算法分精确推理和近似推理. 精确推理有变量消元法和团树传播法; 近似推理算法是基于随机抽样的算法.

#变量消除法是精确推断的一种方法.
from pgmpy.inference import VariableElimination
asia_infer = VariableElimination(cancer_model)
q = asia_infer.query(variables=['Cancer'], evidence={'Smoker': 0})
print(q)

结果:
在这里插入图片描述
案例2:学生成绩贝叶斯网络

在这里插入图片描述
贝叶斯网络变量说明
在这里插入图片描述
实现代码

from pgmpy.models import BayesianModel
from pgmpy.factors.discrete import TabularCPD# 通过边来定义贝叶斯网络结构
stu_model = BayesianModel([('D', 'G'), ('I', 'G'), ('G', 'L'), ('I', 'S')])# 定义条件概率分布
cpd_d = TabularCPD(variable='D', variable_card=2, values=[[0.6], [0.4]])
cpd_i = TabularCPD(variable='I', variable_card=2, values=[[0.7],[0.3]])# variable:变量
# variable_card:基数
# values:变量值
# evidence:
cpd_g = 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]],evidence=['I', 'D'],evidence_card=[2, 2])cpd_l = TabularCPD(variable='L', variable_card=2, values=[[0.1, 0.4, 0.99],[0.9, 0.6, 0.01]],evidence=['G'],evidence_card=[3])cpd_s = TabularCPD(variable='S', variable_card=2,values=[[0.95, 0.2],[0.05, 0.8]],evidence=['I'],evidence_card=[2])# 将有向无环图与条件概率分布表关联
stu_model.add_cpds(cpd_d, cpd_i, cpd_g, cpd_l, cpd_s)# 验证模型:检查网络结构和CPD,并验证CPD是否正确定义和总和为1
print(stu_model.check_model())

使用极大似然估计:

import numpy as np
import pandas as pd
from pgmpy.models import BayesianModel
from pgmpy.estimators import MaximumLikelihoodEstimator, BayesianEstimator
raw_data = np.random.randint(low=0, high=2, size=(1000, 5))
data = pd.DataFrame(raw_data, columns=['D', 'I', 'G', 'L', 'S'])
model = BayesianModel([('D', 'G'), ('I', 'G'), ('I', 'S'), ('G', 'L')])
model.fit(data, estimator=MaximumLikelihoodEstimator)
for cpd in model.get_cpds():print("CPD of {variable}:".format(variable=cpd.variable))print(cpd)

【注意】

  • 安装pgmpy的python环境必须要是python3.7.X版本,X必须大于等于1.
  • 安装pgmpy必须安装以下模块
    networkX
    scipy
    numpy
    pytorch
    tqdm
    pandas
    pyparsing
    statsmodels
    joblib

http://chatgpt.dhexx.cn/article/p895U9MK.shtml

相关文章

Android init.rc中vold socket语法简介

一、 前言 本篇文章以Android4.4代码为例,简单说明init.rc中vold里面socket语法的使用。 二、语法简介 2.1 init.rc位置 init.rc文件位置:/system/core/rootdir/init.rc 2.2 vold代码块位置 service vold /system/bin/voldclass coresocket vold s…

Android 7.0 Vold工作流程

一、Vold工作机制 Vold是Volume Daemon的缩写,它是Android平台中外部存储系统的管控中心,是管理和控制Android平台外部存储设备的后台进程。其功能主要包括:SD卡的插拔事件检测、SD卡挂载、卸载、格式化等。 如上图所示,Vold中的…

1.9 深入理解Vold和Rild

第9章 深入理解Vold和Rild 9.1 概述 本章将分析Android系统中两个比较重要的程序,它们分别是: Vold:Volume Daemon,用于管理和控制Android平台外部存储设备的后台进程,这些管理和控制,包括SD卡的插拔事件…

Android之vold进程启动源码分析

1.Vold (Volume Daemon)介绍 vold进程接收来自内核的外部设备消息,用于管理和控制Android平台外部存储设备,包括SD插拨、挂载、卸载、格式化等;当外部设备发生变化时,内核通过Netlink发送uEvent格式的消息给…

<Android开发> Android vold - 第四篇 vold 的NetlinkHandler类简介

本系列主要介绍 Android vold,分为以下篇章 <Android开发> Android vold - 第一篇 vold前言简介 <Android开发> Android vold - 第二篇 vold 的main()函数简介 <Android开发> Android vold - 第…

<Android开发> Android vold - 第二篇 vold 的main()函数简介

本系列主要介绍 Android vold,分为以下篇章 <Android开发> Android vold - 第一篇 vold前言简介 <Android开发> Android vold - 第二篇 vold 的main()函数简介 <Android开发> Android vold - 第…

Android外部存储设备管理——vold挂载大容量存储设备

一、简介 Vold(volume Daemon),即Volume守护进程,用来管理Android中存储类(USB-Storage,包含U盘和SD卡)的热拔插事件,处于Kernel和Framework之间,是两个层级连接的桥梁。Vold在系统中以守护进程存在&#x…

Android Vold 架构简析

这篇文章中主要是分析一下,android系统里面的Vold——Vold是andorid系统的设备管理器,扮演着linux里面的udev的角色。它通过监听uevent的端口,取得 uevent事件,dispatch到 相应的Listener,执行相应的动作。 UEvent 在…

Android Vold架构

1. 总体架构 2. 流程概览 2.1 开启Vold 2.2 引导Uevent 2.3 处理事件 Vold - Volume Daemon存储类的守护进程,作为Android的一个本地服务,负责处理诸如SD、USB等存储类设备的插拔等事件。 1. 总体架构 Vold服务由volumeManager统一管控&#xff0c…

Vold 流程介绍

文章目录 前言框架MountService 流程Vold 流程 前言 印象中是参考 《深入理解 Android 卷 1 》 追的流程,差不多供参考吧 基于安卓 4.4 框架 MountService 流程 /*【初始化流程总结】: SystemServerinitAndLoop()// 创建 MountService 服务对象mountS…

ANDROID中的VOLD分析

现在可能很少有人会用mknod这个命令了,也很少有使用它的机会,但就在几年前,这还是一项linux工程师的必备技能,在制作文件系统前或加载新的驱动前,我们必须小心翼翼的创建设备节点。 不需要使用mknod并不是他消失了&am…

Android -- Vold机制简要分析

Android -- Vold机制简要分析 Vold是用于管理和控制Android外部存储介质的后台进程,这里说的管控,主要包括SD卡的插拔、挂载/卸载和格式化等;它是Android平台外部存储系统的管控枢纽。 Vold的整个控制模块主要由三个类模块构成:Ne…

Android Vold简介(一)

Vold(volume Daemon),即Volume守护进程,用来管理Android中存储类的热拔插事件,处于Kernel和Framework之间,是两个层级连接的桥梁。先来看一下Vold在Android系统的整体架构。 该图主要包含了Framework和Vold进程的,Ke…

vold

一、Vold工作机制 Vold是Volume Daemon的缩写,它是Android平台中外部存储系统的管控中心,是管理和控制Android平台外部存储设备的后台进程。其功能主要包括:SD卡的插拔事件检测、SD卡挂载、卸载、格式化等。 如上图所示,Vold中的…

Vold工作流程分析学习

一 Vold工作机制分析 vold进程:管理和控制Android平台外部存储设备,包括SD插拨、挂载、卸载、格式化等; vold进程接收来自内核的外部设备消息。 Vold框架图如下: Vold接收来自内核的事件,通过netlink机制。 Netlink 是…

Android vold介绍

目录 1. 前言2. vold概述3. vold初始化|- -vm->start()|- -process_config|- -hardware::configureRpcThreadpool|- -vold::VoldNativeService::start|- -nm->start() 4. StorageManagerService|- -SM与vold建立关联|- - -startService(serviceClass) |- -StorageManager…

<Android开发> Android vold - 第一篇 vold前言简介

本系列主要介绍 Android vold,分为以下篇章 <Android开发> Android vold - 第一篇 vold前言简介 <Android开发> Android vold - 第二篇 vold 的main()函数简介 <Android开发> Android vold - 第…

Vold原理介绍

一、 Vold简介 Android中Vold是volume Daemon,即Volume守护进程,用来管理Android中存储类的热拔插事件。这里的热插拔涉及的场景如: 1. 手机usb以MTP或者传输照片方式插拔PC端后磁盘数据的挂卸载; 2. 设备开关机过程中存储设备各分…

C语言Switch....case用法

概述 C语言switch语句通常用于多个条件判断,根据不同情况执行不同的代码块。它的使用形式如下: switch(表达式) { case 常量表达式1: 语句序列1 break; case 常量表达式2: 语句序列2 break; ...... default…

MySQL 入门:Case 语句很好用

引言 MySQL CASE 是一个 MySQL 语句查询关键字,它定义了处理循环概念以执行条件集并使用 IF ELSE 返回匹配案例的方式。 MySQL 中的 CASE 是一种控制语句,它验证条件案例集,并在第一个案例满足 else 值时显示值并退出循环。 如果没有找到 T…