2

我正在尝试使用库bnlearnRgraphviz. 我的工作流程如下:

在使用随机数据(我实际使用的数据显然不是随机的)创建数据框后,我将数据离散化,结构学习有向无环图(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")

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

# 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 的文档。我感谢任何反馈,如果我没有足够清楚地表达我的想法,我很乐意改变问题中的任何内容。

谢谢你。

4

1 回答 1

2

鉴于证据,如何使用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::nodesasnodesRgraphviz. 我倾向于bnlearn最后加载。

于 2021-09-14T21:41:10.300 回答