Interfacing with the gRain R package
The gRain package
(link)
is available from CRAN and provides the only implementation of exact inference in R; currently it
only supports discrete Bayesian networks. The main data structure in gRain is the
grain
class, which stores a fitted Bayesian network as a list of conditional
probability tables (much like bnlearn's bn.fit
objects) and makes it
possible for setEvidence()
and querygrain()
to perform posterior inference
via belief propagation.
Exporting a fitted Bayesian networks to gRain
bn.fit
objects can be exported with the conversion method as.grain()
.
> library(bnlearn) > > dag = hc(learning.test) > fitted.bnlearn = bn.fit(dag, learning.test) > fitted.grain = as.grain(fitted.bnlearn) > fitted.grain
Independence network: Compiled: TRUE Propagated: FALSE Evidence: FALSE
Only discrete networks can be exported, since gRain does not support networks with other parametric assumptions.
> dag.gbn = hc(gaussian.test) > fitted.gbn = bn.fit(dag.gbn, gaussian.test) > as.grain(fitted.gbn)
## Error: the gRain package only supports discrete networks.
The other important limitation of gRain, compared to bnlearn,
is that it does not allow for conditional probabilities to be NaN
. (This happens when
estimating them via maximum likelihood and some parent configurations are not observed in the data.)
In that case as.grain()
will give a warning and replace the NaN
s with
uniform distributions, much like the Bayesian posterior estimator would.
> fitted.sparse = bn.fit(dag, learning.test[1:10, ]) > as.grain(fitted.sparse)
## Warning in from.bn.fit.to.grain(x): NaN conditional probabilities in D, ## replaced with a uniform distribution.
Independence network: Compiled: TRUE Propagated: FALSE Evidence: FALSE
Importing a network structure from gRain
Importing network structures works in the same way, with a conversion method as.bn.fit()
.
> fitted.import = as.bn.fit(fitted.grain) > all.equal(fitted.bnlearn, fitted.import)
[1] TRUE
For convenience, bnlearn also provides an as.bn()
conversion function
that returns the network structure underlying the grain
object as a bn
object.
> dag.import = as.bn(fitted.grain) > all.equal(dag, dag.import)
[1] TRUE
Note that by default as.bn.fit()
disregards any evidence that has been set in the grain
object with setEvidence()
. So, for instance, setting B
equal to b
does not
have any effect on the conditional probability table for node B
in the returned bn.fit
object.
> library(gRain) > fitted.with.evidence = setEvidence(fitted.grain, node = "B", state = "b") > as.bn.fit(fitted.with.evidence)$B
Parameters of node B (multinomial distribution) Conditional probability table: A B a b c a 0.85611511 0.44491018 0.11492178 b 0.02517986 0.22095808 0.09446450 c 0.11870504 0.33413174 0.79061372
Using the argument including.evidence
will modify the conditional probability table to reflect the
evidence in the grain
object.
> as.bn.fit(fitted.with.evidence, including.evidence = TRUE)$B
Parameters of node B (multinomial distribution) Conditional probability table: A B a b c a 0 0 0 b 1 1 1 c 0 0 0
Mon Aug 5 02:48:50 2024
with bnlearn
5.0
and R version 4.4.1 (2024-06-14)
.