Die Daten, die Sie generieren, werden in bnstruct als DBN mit 3 Schichten behandelt, die jeweils aus einem einzigen Knoten bestehen. Die richtige Behandlung eines Datasets als Sequenz von Ereignissen besteht darin, die Variable X
im Ereignis i
als eine andere Variable als die Variable X
im Ereignis j
zu betrachten, da learn.dynamic.network
nur ein Proxy für learn.network
mit einer impliziten Schichtung ist. Das heißt, Ihr Dataset muss nicht durch Hinzufügen von Zeilen, sondern durch Hinzufügen von Spalten erstellt werden. Abschnitt 4.1.2 der Vignette erklärt, wie man ein DBN lernt.
Der richtige Weg für den Bau und einen Datensatz in Ihrem Beispiel verwenden ist
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 effektive Knoten haben, in 40 Schichten unterteilt.
Zur ersten Frage: Eine Idee ist es, ein initiales Netzwerk als Ausgangspunkt für die aufeinanderfolgenden Zeitschritte bereitzustellen. Unter der Annahme, dass der Datensatz zum Zeitpunkt t+1
durch Hinzufügen neuer Spalten zum Datensatz im Zeitschritt t
erhalten wird, müssen Sie das Objekt BN
manuell anpassen, um den Datensatz darzustellen.
Vom Paket Vignette:
Es ist auch möglich, ein erstes Netzwerk als Ausgangspunkt für die Struktursuche zur Verfügung zu stellen. Dies kann mit dem Argument initial.network
erfolgen, die akzeptiert drei Arten von Eingaben:
- ein
BN
Gegenstand (mit einer Struktur);
- a
matrix
mit der Adjazenzmatrix, die die Struktur eines Netzwerks darstellt;
- die Zeichenfolge
random.chain
für den Start von einem zufällig ausgewählten kettenartigen Netzwerk.
Die einfachste Möglichkeit ist wahrscheinlich ein zu halten, die DAG mit 0
s bei jeder Vergrößerung erweitern, um ein Netzwerk mit mehreren Knoten zu haben, und keine Kanten an den neuen Knoten gehen, und dass neue DAG zu verwenden, wie Startpunkt. In Ihrem Beispiel:
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)
}
Dies wird jedoch das gesamte DBN jedes Mal neu lernen.Wenn Kanten nur auf die unmittelbar folgende Ebene angewendet werden können, können Sie den Suchbereich mit einem layer.struct
-Parameter beschneiden oder indem Sie zwei Ereignisse gleichzeitig lernen und den größeren DBN manuell erstellen.
Für die zweite Frage, bietet derzeit bnstruct keine parallele Verarbeitung.