robertness
12/16/2014 - 5:57 PM

Conditional Entropy for nodes of BNLearn Bayesian Network

Conditional Entropy for nodes of BNLearn Bayesian Network

getEntropy <- function(probDist, base=exp(1)){
  #Calculates entropy given a numeric corresponding to probabilities in a discrete distribution
  -sum(log(probDist, base=base) * probDist)
}

getConditionalEntropyGivenParents <- function(bn.model, node, base){
  #Calculates the conditional entropy of a node given its parents in a fitted bayesian network object from BNLearn package.
  #Only works for discrete valued distributions fitted on data where variables are non-ordered factors.
  #Uses gRain package to convert to independence graph and apply junction tree algo for BN queries.
  #bn.model is a fitted bn.object
  #node is a character name of the node for which to find conditional entropy.  
  #base is the desired base of the logarithm in the entropy calculate.  By setting base equal to the number of levels
  # of the node variable, maximum entropy will be 1.  Set to 2 for entropy units in bits.  
  require(bnlearn)
  require(gRain)
  nodeParents <- bnlearn::parents(bn.model, node)
  levelList <- lapply(nodeParents, function(parent) unique(rownames(bn.model[[parent]]$prob)))
  parentsCombinations <- expand.grid(levelList, stringsAsFactors = FALSE)
  jtree <- compile(as.grain(bn.model))
  conditionalEntropy <- sum(apply(parentsCombinations, 1, function(row){
    evidence.grain <- setFinding(jtree, nodes = nodeParents, states = row)
    conditionalDist <- querygrain(evidence.grain, nodes = node)[[node]]
    comboProb <- pEvidence(evidence.grain)
    getEntropy(conditionalDist, base = base) * comboProb
  }))
  conditionalEntropy
}