0

I got an error when try to use structural.em in "bnlearn" package This is the code:

cut.learn<- structural.em(cut.df, maximize = "hc", 
+               maximize.args = "restart",
+               fit="mle", fit.args = list(),
+               impute = "parents", impute.args = list(), return.all = FALSE,
+               max.iter = 5, debug = FALSE)

Error in check.data(x, allow.levels = TRUE, allow.missing = TRUE, warn.if.no.missing = TRUE, : at least one variable has no observed values.

Did anyone have the same problems, please tell me how to fix it. Thank you.

Patrick Artner
  • 50,409
  • 9
  • 43
  • 69
Wantidah
  • 21
  • 2

1 Answers1

1

I got structural.em working. I am currently working on a python interface to bnlearn that I call pybnl. I also ran into the problem you desecribe above.

Here is a jupyter notebook that shows how to use StructuralEM from python marks.

The gist of it is described in slides-bnshort.pdf on page 135, "The MARKS Example, Revisited".

You have to create an inital fit with an inital imputed dataframe by hand and then provide the arguments to structural.em like so (ldmarks is the latent-discrete-marks dataframe where the LAT column only contains missing/NA values):

library(bnlearn)
data('marks')
dmarks = discretize(marks, breaks = 2, method = "interval")
ldmarks = data.frame(dmarks, LAT = factor(rep(NA, nrow(dmarks)), levels = c("A", "B")))

imputed = ldmarks
# Randomly set values of the unobserved variable in the imputed data.frame
imputed$LAT = sample(factor(c("A", "B")), nrow(dmarks2), replace = TRUE)

# Fit the parameters over an empty graph
dag = empty.graph(nodes = names(ldmarks))
fitted = bn.fit(dag, imputed)
# Although we've set imputed values randomly, nonetheless override them with a uniform distribution
fitted$LAT = array(c(0.5, 0.5), dim = 2, dimnames = list(c("A", "B")))

# Use whitelist to enforce arcs from the latent node to all others
r = structural.em(ldmarks, fit = "bayes", impute="bayes-lw", start=fitted, maximize.args=list(whitelist = data.frame(from = "LAT", to = names(dmarks))), return.all = TRUE)  

You have to use bnlearn 4.4-20180620 or later, because it fixes a bug in the underlying impute function.

bojan
  • 363
  • 3
  • 5
cs224
  • 328
  • 2
  • 12