danielkorzekwa / bayes-scala

Bayesian Networks in Scala
Other
205 stars 39 forks source link

Sepsets containing a single variable #11

Open HarryLynas opened 10 years ago

HarryLynas commented 10 years ago

I was having an issue with the common benchmarking Bayesian network "B" and so decided to test this with a much smaller network, commonly used when learning what a Bayesian network is (Grass Wet).

image

The code I am using to represent this network is shown below:

  var loopyBP: LoopyBP = _

  def loadNetwork() {
    var rain = Var(1, 2)
    var sprinkler = Var(2, 2)
    var grasswet = Var(3, 2)

    var rainFac = Factor(Array(rain), Array(0.3, 0.7))
    var sprinklerFac = Factor(Array(sprinkler, rain), Array(0.01, 0.99, 0.7, 0.3))
    var grasswetFac = Factor(Array(grasswet, sprinkler, rain), Array(1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0))

    var clusterGraph = GenericClusterGraph()
    clusterGraph.addCluster(1, rainFac)
    clusterGraph.addCluster(2, sprinklerFac)
    clusterGraph.addCluster(3, grasswetFac)

    clusterGraph.addEdges((1, 2), (1, 3), (2, 3))

    loopyBP = LoopyBP(clusterGraph)
    loopyBP.calibrate()
  }

However when adding the edges the following error is obtained:

"requirement failed: Sepset must contain single variable only"

Which can be found within this code:

  private def calcSepsetVariable(cluster1: Cluster, cluster2: Cluster): Var = {
    val intersectVariables = cluster1.getFactor().getVariables().intersect(cluster2.getFactor().getVariables())
    require(intersectVariables.size == 1, "Sepset must contain single variable only")
    val intersectVariable = intersectVariables.head

    intersectVariable
  }

Essentially as far as I am aware this algorithm is saying the network is invalid when actually as a Bayesian network this should be fine.

I am wondering if there is some sort of mistake I am making or if Bayes-Scala does not yet support this?

danielkorzekwa commented 10 years ago

It's a limitation of Bayes-Scala, the intersection of two connected clusters cannot contain more than one variable. The work around is to combine sprinkler and grasswet factors into a single cluster, simply take a product of both factors. Then you would have two clusters only with rain var in a sepset.

Eventually, feel free to change LoopyBP implementation yourself to support sepsets with multiple factors.

HarryLynas commented 10 years ago

Okay, thank you for the fast reply.

danielkorzekwa commented 9 years ago

Proposes solutions: 1) Fix it in the cluster graph inference - support multivariable sepsets. 2) Support discrete networks in the factor graph inference.

francisdb commented 9 years ago

Just mentioning that we are also hitting this one...