我正在寻找一种使用 bnstruct 包训练动态贝叶斯网络 (DBN) 的方法,以应对从类似事件收集数据的特殊情况。因此,1)我想训练我的 DBN,每次只用一个事件来喂养它。
在实际情况下,事件数、行数和列数都很大,2) 如果可以实现一些并行处理来提高性能,那就更好了。
下面提供了一个虚拟代码,其中所有数据都必须立即输入,无论事件边界如何。
library(bnstruct)
numEvents <- 40
numRows <- 5
numCols <- 3
mat <- matrix(data = rnorm(numEvents * numRows * numCols), ncol = numCols)
varNames <- paste0("var", 1:numCols)
colnames(mat) <- varNames
dataset <- BNDataset(data = mat, discreteness = rep(F, ncol(mat)), variables = varNames, node.sizes = rep(3, ncol(mat)))
dbn <- learn.dynamic.network(dataset, num.time.steps = numCols)
谢谢。
最佳答案
您生成的数据在 bnstruct 中被视为具有 3 层的 DBN,每层由一个节点组成。将数据集视为事件序列的正确方法是将事件 i
中的变量 X
视为与同一变量 X
不同的变量在事件 j
中,因为 learn.dynamic.network
只是具有隐式分层的 learn.network
的代理。也就是说,您的数据集不必通过添加行来构建,而是通过添加列来构建。
插图第 4.1.2 节解释了如何学习 DBN。
在示例中构建和使用数据集的正确方法是
mat <- matrix(data = rnorm(numEvents * numRows * numCols), ncol = numCols * numEvents)
varNames <- rep(paste0("var", 1:numCols), numEvents)
colnames(mat) <- varNames
dataset <- BNDataset(data = mat, discreteness = rep(F, ncol(mat)), variables = varNames, node.sizes = rep(3, ncol(mat)))
dbn <- learn.dynamic.network(dataset, num.time.steps = numEvents)
dbn
将有 120 个有效节点,分为 40 层。
回到第一个问题:一个想法是提供一个初始网络作为连续时间步骤的起点。假设时间步t+1
的数据集是通过向时间步t
使用的数据集添加新列获得的,您必须手动调整BN
对象来表示数据集。
来自包小插图:
It is also possible to provide an initial network as starting point for the structure search. This can be done using the
initial.network
argument, which accepts three kinds of inputs:
- a
BN
object (with a structure);- a
matrix
containing the adjacency matrix representing the structure of a network;- the string
random.chain
for starting from a randomly sampled chain-like network.
最简单的选择可能是在每次扩充时使用 0
来扩展 DAG,拥有一个具有更多节点的网络,并且没有连接到新节点的边,并使用新的DAG 作为起点。在您的示例中:
library(bnstruct)
numEvents <- 40
numRows <- 5
numCols <- 3
mat <- matrix(data = rnorm(numRows * numCols), ncol = numCols)
varNames <- paste0("var", 1:numCols)
colnames(mat) <- varNames
dataset <- BNDataset(data = mat,
discreteness = rep(F, ncol(mat)),
variables = varNames,
node.sizes = rep(3, ncol(mat)))
dbn <- learn.network(dataset)
for (event in 2:numEvents) {
# collect new data
new.mat <- matrix(data = rnorm(numRows * numCols), ncol = numCols)
colnames(new.mat) <- paste0(varNames, "_", event)
mat <- cbind(mat, new.mat)
dataset <- BNDataset(data = mat,
discreteness = rep(F, ncol(mat)),
variables = colnames(mat),
node.sizes = rep(3, ncol(mat)))
# expand structure of the DBN, adding the nodes relative to the new event
dbn.dag <- dag(dbn)
n.nodes <- ncol(dbn.dag)
new.dag <- matrix(0, nrow=ncol(mat), ncol=ncol(mat))
new.dag[1:n.nodes, 1:n.nodes] <- dbn.dag
# learn
dbn <- learn.dynamic.network(dataset,
initial.network = new.dag,
num.time.steps = event)
}
然而,这每次都会重新学习整个 DBN。如果边缘只能到达紧邻的下一层,您可以通过提供 layer.struct
参数来修剪搜索空间,或者通过学习一次使用两个事件并手动构建更大的 DBN。
对于第二个问题,bnstruct目前不提供并行处理。
关于r - 动态贝叶斯网络 - 多元 - 重复事件 - bnstruct R Package,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42221112/