贝叶斯网的R实现( Bayesian networks in R)bnlearn(4)

贝叶斯网络的推理(inference)

(1)推理问题 在了解如何构造贝叶斯网络之后,下面我们考虑如何利用贝叶斯网络来进行推理。贝叶斯网络的推理是对某些变量当给定其它变量的状态作为证据时如何推断它们的状态,也就是通过计算回答查询(query)的过程。这个推理的过程也称为概率推理或信念更新。 在实践中,贝叶斯网的推理基于贝叶斯统计,重点在于后验概率或密度的计算。推理问题可分为这样的三类: (a)后验概率分布问题 这类问题是已知某些变量的取值,计算另一些变量的后验概率分布。已知的变量可称为证据变量(evidence variables),记作E,取值记为e。需要计算后验概率分布的变量叫查询变量,记为Q。按证据变量和因果变量的不同逻辑关系,这种概率推理又可分成:从结果到原因的推理、从原因到结果的推理、同一结果的不同原因的关联推理以及包含以上三种的混合推理。 (b)最大后验假设问题(MAP) (c)最大可能解释问题(MPE)

(2)推理问题的算法及实例

贝叶斯网络的概率推理的算法可分成两种:精确推理(exact inference)和近似推理(approximate inference)。这两种推理都建立在前面所介绍的贝叶斯网的基本性质的基础上,目的是通过使用局部(边缘概率分布)的计算来避免计算(联合概率分布)的复杂程度。

精确推断组合了使用局部计算的贝叶斯定理的重复应用来得到条件概率或条件概率密度的精确值。然而,这种方法的可行性是有限的,局限于小的或者非常简单的网络上。

两种最著名的精确推断算法是变量消元法和团树传播法(又称联合树算法)。这两种方法最早都起源于离散的网络,然后又扩展应用到连续网络和混合网络。变量消元算法直接利用贝叶斯网的结构,指定了局部分布上的最优的序列运算以及如何存贮中间结果以避免不确定的计算。团树传播算法是把贝叶斯网变换成一个联合树(junction tree)来执行。联合树是moral图的变换,是一个无向树,树中的每一个节点称为团(clique),由原贝叶斯网络中的一组随机变量构成,是无向图中最大的全连通子图。。

下面是团树传播算法的步骤:

创建moral图:将原贝叶斯网络中同一节点的父节点两两相连,同时去掉每一条连接边的箭头,得到moral图。
三角化(Triangulating):对包含4个及以上个节点数的环,增加一条无向边将环中两个非相邻节点连接起来,完成对moral 图的三角化。
识别团(clique)节点:在三角化图中,识别团,每个团都是无向图的子图。- 联合树:建立包含所有团的联合树,交集作为连接两个团的分隔节点。
重参数化:是用原贝叶斯网的局部分布的参数去计算联合树中复合节点的参数集合。
在R中,gRain包compile函数对离散的贝叶斯网运用了上面所述的团树传播算法。

asia网络(又称为chest clinic)是早期贝叶斯网文献中的给出的一个网络。我们以这个网络为例,说明贝叶斯网查询函数的用法。 这是一个离散的网络。首先使用bnlearn包的model2work函数建立这个网络:呼吸困难(dyspnoea)可能由于肺结核(tuberculosis),肺癌(lung cancer)或者支气管炎(brochitis)的某一种(或几种),也可能有其它来源。最近到亚洲旅行会增加肺结核感染的风险,同时吸烟也是一个众所周知的产生肺癌和支气管炎的风险因素。一次胸腔X光不能在肺癌和肺结核之间做出判断,这三种疾病都不能由有没有呼吸困难来确诊。

library(bnlearn)
library(gRain)

# 利用条件概率表生成网络
asianet <- model2network("[asia][smoke][tub|asia][lung|smoke][bronc|smoke][either|tub:lung][xray|either][dysp|bronc:either]")
yn <- c("yes", "no")
cptA <- matrix(c(0.01, 0.99), ncol = 2, dimnames = list(NULL, yn))
cptS <- matrix(c(0.5, 0.5), ncol = 2, dimnames = list(NULL, yn))
cptT <- matrix(c(0.05, 0.95, 0.01, 0.99), ncol = 2, dimnames = list(tub = yn, 
    asia = yn))
cptL <- matrix(c(0.1, 0.9, 0.01, 0.99), ncol = 2, dimnames = list(lung = yn, 
    smoke = yn))
cptB <- matrix(c(0.6, 0.4, 0.3, 0.7), ncol = 2, dimnames = list(bronc = yn, 
    smoke = yn))
cptE <- c(1, 0, 1, 0, 1, 0, 0, 1)
dim(cptE) <- c(2, 2, 2)
dimnames(cptE) <- list(either = yn, lung = yn, tub = yn)
cptX <- matrix(c(0.98, 0.02, 0.05, 0.95), ncol = 2, dimnames = list(xray = yn, 
    either = yn))
cptD <- c(0.9, 0.1, 0.7, 0.3, 0.8, 0.2, 0.1, 0.9)
dim(cptD) <- c(2, 2, 2)
dimnames(cptD) <- list(dysp = yn, either = yn, bronc = yn)
asianet.fit <- custom.fit(asianet, dist = list(asia = cptA, smoke = cptS, tub = cptT, 
    lung = cptL, bronc = cptB, either = cptE, xray = cptX, dysp = cptD))

plot(asianet)


# moral图
asianet.m <- moral(asianet)
plot(asianet.m)


# 精确查询
asia.jtree <- compile(as.grain(asianet.fit))
summary(asia.jtree)
## Independence network: Compiled: TRUE Propagated: FALSE 
## Nodes : Named chr [1:8] "asia" "bronc" "dysp" "either" "lung" ...
## - attr(*, "names")= chr [1:8] "asia" "bronc" "dysp" "either" ...
## Number of cliques: 6 
## Maximal clique size: 3 
## Maximal state space in cliques: 8

asia.ev1 <- setFinding(asia.jtree, nodes = c("asia", "dysp"), states = c("yes", 
    "yes")) #设定证据
querygrain(asia.ev1, nodes = "lung", type = "marginal") #在证据之下查询
## $lung
## lung
## yes no 
## 0.1135 0.8865
querygrain(asia.jtree, nodes = "lung", type = "marginal") #无证据下的查询
## $lung
## lung
## yes no 
## 0.055 0.945
compile函数可以编译一个贝叶斯网,创建团树并建立潜在的团,其参数(要编译的网络)要求是grain对象,使用as.grain对bnlearn对象asianet.fit进行变换。setFinding函数是用来设定查询条件,在这里我们设定证据为节点"asia",“dysp"各自取状态“yes”。querygrain函数是在给定证据的条件下,对网络进行查询,得到查询变量(这里是“lung”)的边缘分布(设定type参数,也可以得到条件分布或联合分布)。

下面在看近似推理。 最常用的近似推理算法是基于随机抽样的算法,也就是蒙特卡罗方法。该算法不利用条件独立性,也不考虑概率分布的特征,而是通过抽样得到一组满足一定概率分布的样本,然后用这些样本进行统计计算。目前主要有两类随机抽样算法:重要性抽样法和马尔可夫链蒙特卡罗方法。最早也是最简单的一种重要性抽样法是Henrion提出的概率逻辑抽样法。它对没有证据变量的网络进行推理时非常有效,当网络中加入证据变量时,尤其是当证据变量的先验概率极小时,这种推理算法收敛将会非常慢, 因此Fung等提出了似然加权法加以改进。

bnlearn包的cpdist函数和cpquery函数使用了近似推断算法。其中cpquery返回一个数值,以证据evidence为条件下事件event的条件概率;cpdist返回一个数据框,包含生成于以证据evidence为条件的节点nodes的条件分布的观测。

# 近似查询,接上面的程序 给定证据,查询事件发生的概率
set.seed(1000)
cpquery(asianet.fit, event = (lung == "yes"), evidence = (asia == "yes") & (dysp == 
    "yes"))
## [1] 0.133

lung.sample <- cpdist(asianet.fit, nodes = "lung", evidence = (asia == "yes") & 
    (dysp == "yes"))
prop.table(table(lung.sample))
## lung.sample
## yes no 
## 0.119 0.881

在这里,我们使用cpquery函数对网络asianet.fit对事件“lung”取值"yes"进行查询,设定证据为节点"asia”,“dysp"各自取状态“yes”;使用cpdist对网络进行查询,在给定上述证据的条件下,得到节点"lung"的条件概率分布表。

你可能感兴趣的:(贝叶斯分类算法)