您正在生成的数据在bnstruct中被视为具有3层的DBN,每个层由单个节点组成。将数据集视为一系列事件的正确方法是将事件i
中的变量X
视为与事件j
中的相同变量X
不同的变量,因为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
对象以表示数据集。
从包晕影:
另外,也可以提供一种初始网络作为起始点 结构搜索。这可以通过使用initial.network
参数,它 接受3种输入来完成:
- 一个
BN
对象(的结构);
- a
matrix
包含表示网络结构的邻接矩阵;
- 字符串
random.chain
用于从随机采样的链状网络 开始。
最简单的方法可能是在每一个扩充,以保持一个扩大DAG与0
S,有更多的节点的网络,也没有边去到新节点,并使用新的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此刻不提供并行处理。