貝葉斯網的R實現( Bayesian networks in R)bnlearn(1)
貝葉斯網bayesian networks是一種有向無環圖模型(DAG),可表示為G=(V,A)。其中V是節點的集合,節點表示隨機變數;A是弧(或稱為邊)的集合,弧的箭頭表示隨機變數之間的概率相依性。有向無環圖DAG定義了一個因子化的V中全體節點的聯合概率分佈,稱為全域性概率分佈;相對的,與每個隨機變數關聯的,為區域性概率分佈。
因子化的形式由貝葉斯網的馬爾科夫性質給出,對每個隨機變數,其概率只依賴於其父代:
可以通過學習演算法得到貝葉斯網的結構。學習演算法首先是學習網路結構,然後在此基礎上估計區域性分佈函式的引數。 儘管全域性和區域性分佈的選擇形式很多,最常用的還是下面的兩種分佈: 多項分佈(離散資料) 多元正態分佈(連續分佈)
得到網路結構,可以利用概率的條件相依,對相關專業問題進行推斷。
R中有多個包可以實現貝葉斯網的建立、學習和推斷,詳見下面表格。
前面我曾簡單介紹過gRain包,本篇討論最常用的bnlearn包。
2.網路建立和操作 bnlearn包自帶資料集marks,88學生5門課的成績。這個資料最早由Mardia et al(1979)研究過。
library(bnlearn)
## Warning: package 'bnlearn' was built under R version 3.0.1
data(marks)
str(marks)
## 'data.frame': 88 obs. of 5 variables:
## $ MECH: num 77 63 75 55 63 53 51 59 62 64 ...
## $ VECT: num 82 78 73 72 63 61 67 70 60 72 ...
## $ ALG : num 67 80 71 63 65 72 65 68 58 60 ...
## $ ANL : num 67 70 66 70 70 64 65 62 62 62 ...
## $ STAT: num 81 81 81 68 63 73 68 56 70 45 ...
建立一個空網路,節點對應於marks的變數。然後通過指派一個兩列的矩陣來新增邊。
生成一個無向圖:
ug <- empty.graph(names(marks))
arcs(ug, ignore.cycles = TRUE) = matrix(c("MECH", "VECT", "MECH", "ALG", "VECT",
"MECH", "VECT", "ALG", "ALG", "MECH", "ALG", "VECT", "ALG", "ANL", "ALG",
"STAT", "ANL", "ALG", "ANL", "STAT", "STAT", "ALG", "STAT", "ANL"), ncol = 2,
byrow = TRUE, dimnames = list(c(), c("from", "to")))
ug
##
## Random/Generated Bayesian network
##
## model:
## [undirected graph]
## nodes: 5
## arcs: 6
## undirected arcs: 6
## directed arcs: 0
## average markov blanket size: 2.40
## average neighbourhood size: 2.40
## average branching factor: 0.00
##
## generation algorithm: Empty
這個ug物件屬於bn類,這個類用於在bnlearn包中管理網路結構。 這個物件包括三個方面的資訊:
(1)learning:結構的學習 (2)node 節點 (3)arc 邊
生成一個有向圖:
dg <- empty.graph(names(marks))
arcs(dg) = matrix(c("VECT", "MECH", "ALG", "MECH", "ALG", "VECT", "ANL", "ALG",
"STAT", "ALG", "STAT", "ANL"), ncol = 2, byrow = TRUE, dimnames = list(c(),
c("from", "to")))
dg
##
## Random/Generated Bayesian network
##
## model:
## [STAT][ANL|STAT][ALG|ANL:STAT][VECT|ALG][MECH|VECT:ALG]
## nodes: 5
## arcs: 6
## undirected arcs: 0
## directed arcs: 6
## average markov blanket size: 2.40
## average neighbourhood size: 2.40
## average branching factor: 1.20
##
## generation algorithm: Empty
有時候也可以從鄰接矩陣(adjacency matrix)來生成有向圖dg。
mat <- matrix(c(0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1,
0, 0, 0, 0, 0), nrow = 5, dimnames = list(nodes(dg), nodes(dg)))
mat
## MECH VECT ALG ANL STAT
## MECH 0 0 0 0 0
## VECT 1 0 0 0 0
## ALG 1 1 0 0 0
## ANL 0 0 1 0 0
## STAT 0 0 1 1 0
dg2 <- empty.graph(nodes(dg))
amat(dg2) <- mat
all.equal(dg, dg2)
## [1] TRUE
手工修改一個已經存在的網路,利用加邊(set.arc)、去邊(drop.arc)、顛倒(rev.arc)這幾個操作,也可以得到一個需要的網路。
dg3 <- empty.graph(nodes(dg))
dg3 <- set.arc(dg3, "VECT", "MECH")
dg3 <- set.arc(dg3, "ALG", "MECH")
dg3 <- set.arc(dg3, "ALG", "VECT")
dg3 <- set.arc(dg3, "ANL", "ALG")
dg3 <- set.arc(dg3, "STAT", "ALG")
dg3 <- set.arc(dg3, "STAT", "ANL")
all.equal(dg, dg3)
## [1] TRUE
all.equal(ug, moral(dg)) #moral圖
## [1] TRUE
我們全面希望瞭解網路的結構,可以使用儲存在每個節點的資訊。
(1)節點的拓撲順序
node.ordering(dg)
## [1] "STAT" "ANL" "ALG" "VECT" "MECH"
(2)節點的鄰居(nbr)和Markov毯(mb)
Markov毯是指對一個節點A,它的所有父節點,子節點以及和A有相同子節點的其它節點 。
nbr(dg, "STAT")
## [1] "ALG" "ANL"
mb(dg, "STAT")
## [1] "ALG" "ANL"
"ANL" %in% mb(dg, "STAT")
## [1] TRUE
"STAT" %in% mb(dg, "ANL")
## [1] TRUE
(3)某個給定節點的子代(child)和父代(parents)和子代的其它父代(o.par)
child <- children(dg, "STAT")
pa <- parents(dg, "STAT")
2.繪製網路
bnlearn包有兩種對bn物件繪製網路結構的方法,一種是利用graph包和Rgraphviz包提供的介面給出的一些繪圖函式,比如graphviz.plot。再一種方法是利用plot函式。下面對於dg,來繪製網路圖。 使用graphviz.plot的好處在於它返回一個graph物件,便於對網路的進一步操作。
library(Rgraphviz)
graphviz.plot(dg, layout = "fdp")

plot(dg, radius = 200, arrow = 30)

