Parameter Learning

library(abn)

In this vignette, we will discuss the parameter learning in the context of additive Bayesian network modelling with the package abn.

Background

In the context of additive Bayesian network (ABN) modelling, parameter learning refers to the process of estimating the parameters of the graphical model. The parameters of the model are the coefficients of the linear regression models that are used to model the conditional probability distributions of the nodes in the network. They are estimated using the data that is available for the nodes in the network.

Fitting an ABN model

The fitAbn() function is used to estimate the parameters of an ABN model. In principle, we need the data and a directed acyclic graph (DAG) that specifies the structure of the network. These, together with additional arguments, are provided by an object of abnLearned to fitAbn() which will then estimate the parameters of the model. This process is illustrated in the vignette("01_quick_start_example").

Alternatively, with fitAbn() we can fit the parameters to a manually specified DAG. In this case, we need to provide the data, its distributions and the DAG as arguments to fitAbn():

# Load an illustrative subset of the example data
mydat <- ex0.dag.data[,c("b1","b2","b3","g1","b4","p2","p4")]

# Specify the distributions of the nodes
mydists <- list(b1="binomial",
                b2="binomial",
                b3="binomial",
                g1="gaussian",
                b4="binomial",
                p2="poisson",
                p4="poisson" )

# Define a DAG
mydag <- matrix(data=c( 0,0,1,0,0,0,0, # b1<-b3
                        1,0,0,0,0,0,0, # b2<-b1
                        0,0,0,0,0,0,0, #
                        0,0,0,0,1,0,0, # g1<-b4
                        0,0,0,0,0,0,0, #
                        0,0,0,0,0,0,0, #
                        0,0,0,0,0,0,0 #
), byrow=TRUE,ncol=7)
colnames(mydag) <- rownames(mydag) <- names(mydat)

Fit the model to calculate the log marginal likelihood goodness of fit:

myres.c <- fitAbn(dag = mydag,
                  data.df = mydat,
                  data.dists = mydists,
                  method = "bayes")
plot(myres.c)
plot of chunk unnamed-chunk-3
plot of chunk unnamed-chunk-3

Examine the parameter estimates

We can examine the parameter estimates with the print() method for the class abnFit

print(myres.c)
#> The ABN model was fitted using a Bayesian approach. The estimated modes (the highest posterior density values of the parameters) are:
#> 
#> $b1
#> b1|(Intercept)          b1|b3 
#>          0.217         -0.164 
#> 
#> $b2
#> b2|(Intercept)          b2|b1 
#>         0.0286         0.0465 
#> 
#> $b3
#> b3|(Intercept) 
#>         0.0267 
#> 
#> $g1
#> g1|(Intercept)          g1|b4   g1|precision 
#>        -0.0494         0.0915         1.0054 
#> 
#> $b4
#> b4|(Intercept) 
#>           0.16 
#> 
#> $p2
#> p2|(Intercept) 
#>           2.34 
#> 
#> $p4
#> p4|(Intercept) 
#>           2.32 
#> 
#> Number of nodes in the network:  7

or by looking at the coef slot of the abnFit object returned by fitAbn():

Examine the marginal posterior densities

Furthermore, we can examine the marginal posterior densities of the parameters. This is useful to assess the uncertainty in the parameter estimates and to check if the model is overfitting the data.

Now fit the model with compute.fixed=TRUE to calculate the marginal posterior distributions for all parameters:

myres.c2 <- fitAbn(dag = mydag,
                  data.df = mydat,
                  data.dists = mydists,
                  method = "bayes",
                  compute.fixed=TRUE)

The marginals slot of the abnFit object returned by fitAbn() contains a list of all marginal posterior densities. We can plot some of the marginal posterior densities to assess the uncertainty in the parameter estimates:

library(ggplot2)
library(gridExtra)

df1 <- as.data.frame(myres.c2$marginals$b1[["b1|(Intercept)"]])
names(df1) <- c("x","y")
p1 <- ggplot(df1, aes(x=x, y=y)) +
  geom_line() +
  geom_point(shape = 43, color="green") +
  labs(x="b1|(Intercept)", title="Node b1, Intercept")

df2 <- as.data.frame(myres.c2$marginals$g1[["g1|b4"]])
names(df2) <- c("x","y")
p2 <- ggplot(df2, aes(x=x, y=y)) +
  geom_line() +
  geom_point(shape = 43, color="orange") +
  labs(x="g1|b4", title="Node g1, parameter b4")

grid.arrange(p1, p2, ncol=2)

plot of chunk unnamed-chunk-6 Note that, by default, all variables are standardized (centre = TRUE).