user2626597
user2626597

Reputation: 61

Drop node from a bayesian network with bnlearn package

I built a network with bnlearn, but there are some nodes without edges to another node, so I would like to remove them. Is there a command to remove a specific node from a bn object?

Upvotes: 3

Views: 1649

Answers (4)

RichardBJ
RichardBJ

Reputation: 377

I interpreted this question a little differently, for me, in R this was my approach: Given we have a network iam:

all_nodes <- nodes(iam)
# Find connected nodes
connected_nodes <- unique(unlist(
         lapply(all_nodes, function(n) mb(iam, n))))

 # Create a subgraph with only the connected nodes
 connected_graph <- subgraph(iam, connected_nodes)

Upvotes: 0

wordsforthewise
wordsforthewise

Reputation: 15777

bnlearn has built-in arc operations (docs also here) made for just this. These functions also have the benefit of checking for cycles in your graph, because Bayesian Networks need to be acyclic (directed acyclic graphs, or DAGs), otherwise you get infinite loops and can't calculate conditional probabilities. There's also a check.illegal argument that checks for another violation of the model when adding an arc (see the docs).

But, their example is not great and neither are the docs. The operations return a model, so you have to overwrite your old model with the returned one.

data(learning.test)
# model ends up the same every time here, but may want
# to set random seed for reproducibility in other cases
set.seed(42)
model = tabu(learning.test)  # tabu is a better algo than hc I think
plot(model)

model <- set.arc(model, "A", "F")
plot(model)
model <- drop.arc(model, "A", "F")
plot(model)

set.edge sets undirected edges, while set.arc sets directed edges.

Upvotes: 3

Mery Romero
Mery Romero

Reputation: 19

Fabiola's answer help me a lot.

Here it is a way to do the same but without having to change the model string by hand.

This is the first time I answer a question, so, please be easy on me regarding format.

"net" is my network, "TARGET_NODE" is the node I want to predict (I am including it within the list to be double sure I don't delete it) and "uniq" my dataset.

model.string <- modelstring(net)
final_nodes <- unique(c(unlist(list(net$arcs)), TARGET_NODE))
nodes_to_delete <- paste("\\[",setdiff(names(net$nodes), final_nodes),"]", sep = "")
for (i in 1:length(nodes_to_delete)) {model.string <- gsub(nodes_to_delete[i], "", model.string)}
net <- model2network(model.string)

cols <- c(match(final_nodes, names(uniq)))
uniq <- uniq[,cols]

Upvotes: 1

Fabiola Fern&#225;ndez
Fabiola Fern&#225;ndez

Reputation: 272

So my attempt for this has been to use the modelstring function. Get the string, remove the node I know it hasn't any arcs/edges - I do this by hand -, save to a new modified string and then convert the string to a network again with the command model2network. Here is the sequence of commands:

model.string <- modelstring(mymodel)
model.string
new.string <- "your string except the node you want to remove from the output above"
new.model <- model2network(new.string)

I guess that would work if you don't have many nodes in total (I've got 22) and you just want to remove a few from the list.

Hope that helps!

Upvotes: 1

Related Questions