【问题标题】:How do I graph a Bayesian Network with instantiated nodes using bnlearn and graphviz?如何使用 bnlearn 和 graphviz 绘制具有实例化节点的贝叶斯网络?
【发布时间】:2021-11-10 00:39:57
【问题描述】:

我正在尝试使用库 bnlearnRgraphviz 绘制带有实例化节点的贝叶斯网络 (BN)。我的工作流程如下:

用随机数据创建数据框后(我实际使用的数据显然不是随机的)然后离散数据,结构学习有向无环图(DAG),将数据拟合到 DAG,然后绘制 DAG .我还绘制了一个 DAG,它显示了每个节点的后验概率。

#rm(list = ls())
library(bnlearn)
library(Rgraphviz)

# Generating random dataframe
data_clean <- data.frame(a = runif(min = 0, max = 100, n = 1000),
                         b = runif(min = 0, max = 100, n = 1000),
                         c = runif(min = 0, max = 100, n = 1000),
                         d = runif(min = 0, max = 100, n = 1000),
                         e = runif(min = 0, max = 100, n = 1000))

# Discretising the data into 3 bins
bins <- 3
data_discrete <- discretize(data_clean, breaks = bins)

# Creating factors for each bin in the data
lv <- c("low", "med", "high")

for (i in names(data_discrete)){
  levels(data_discrete[, i]) = lv
}

# Structure learning the DAG from the training set
whitelist <- matrix(c("a", "b",
                      "b", "c",
                      "c", "e",
                      "a", "d",
                      "d", "e"),
                    ncol = 2, byrow = TRUE, dimnames = list(NULL, c("from", "to")))

bn.hc <- hc(data_discrete, whitelist = whitelist)

# Plotting the DAG
dag.hc <- graphviz.plot(bn.hc,
                        layout = "dot")

# Fitting the data to the structure
fitted <- bn.fit(bn.hc, data = data_discrete, method = "bayes")

# Plotting the DAG with posteriors
graphviz.chart(fitted, type = "barprob", layout = "dot")

接下来我要做的是手动更改分配给fittedbn.fit 对象中的分布,然后绘制一个显示实例化节点和响应变量e 的更新后验概率的DAG。

# Manually instantiating
fitted_evidence <- fitted

cpt.a = matrix(c(1, 0, 0), ncol = 3, dimnames = list(NULL, lv))

cpt.c = c(1, 0, 0,
          0, 1, 0,
          0, 0, 1)
dim(cpt.c) <- c(3, 3)
dimnames(cpt.c) <-  list("c" = lv, "b" =  lv)

cpt.b = c(1, 0, 0,
          0, 1, 0,
          0, 0, 1)
dim(cpt.b) <- c(3, 3)
dimnames(cpt.b) <-  list("b" = lv, "a" =  lv)

cpt.d = c(0, 0, 1,
          0, 1, 0,
          1, 0, 0)
dim(cpt.d) <- c(3, 3)
dimnames(cpt.d) <-  list("d" = lv, "a" =  lv)

fitted_evidence$a <- cpt.a
fitted_evidence$b <- cpt.b
fitted_evidence$c <- cpt.c
fitted_evidence$d <- cpt.d

# Plotting the DAG with instantiation and posterior for response
graphviz.chart(fitted_evidence, type = "barprob", layout = "dot")

这是我得到的结果,但我的实际 BN 更大,弧线更多,手动更改 bn.fit 对象是不切实际的。

我想知道是否有一种方法可以在不手动更改bn.fit 对象的情况下通过实例化绘制 DAG?是否有我缺少的解决方法或功能?

我认为/希望我已经彻底阅读了 bnlearn 的文档。如果我没有足够清楚地表达我的想法,我很感激任何反馈,并且很乐意更改问题中的任何内容。

谢谢。

【问题讨论】:

    标签: r bnlearn r-graphviz


    【解决方案1】:

    在给定证据的情况下,使用cpdist 从后验中抽取样本怎么样。然后,您可以使用bn.fit 使用cpdist 样本估计更新的参数。然后像以前一样绘制。

    一个例子:

    set.seed(69184390) # for sampling
    
    # Your evidence vector
    ev <- list(a = "low", b="low", c="low", d="high")
    
    # draw samples
    updated_dat <- cpdist(fitted, nodes=bnlearn::nodes(fitted), evidence=ev, method="lw", n=1e6)
    
    # refit : you'll get warnings over missing levels
    updated_fit <- bn.fit(bn.hc, data = updated_dat)
    
    # plot
    par(mar=rep(0,4))
    graphviz.chart(updated_fit, type = "barprob", layout = "dot")
    

    注意我使用了bnlearn::nodes,因为nodesRgraphviz 的依赖所掩盖。我倾向于最后加载bnlearn

    【讨论】:

    • 太棒了,效果很好。谢谢你。我将不得不在我更大的网络上尝试它,但我不明白为什么它不起作用。你让我很开心;)
    猜你喜欢
    • 2017-03-29
    • 2021-11-24
    • 1970-01-01
    • 2013-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-09
    相关资源
    最近更新 更多