2017-02-14 44 views
1

我正在寻找一种方法来训练动态贝叶斯网络(DBN),使用包bnstruct,用于从类似事件收集数据的特殊情况。因此,1)我想训练我的DBN每次给它提供一个事件。在实际情况下,事件,行和列的数量很大,2)如果可以实现某些并行处理以提高性能,那将会更好。动态贝叶斯网络 - 多变量 - 重复性事件 - bnstruct R包

下面提供了一个虚拟代码,其中所有数据都必须立即输入,忽略事件边界。

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) 

谢谢。

回答

2

您正在生成的数据在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此刻不提供并行处理。