Code for "Bayesian models and causality"
/* | |
Setup: | |
$ git clone https://github.com/jliszka/probability-monad.git | |
$ cd probability-monad | |
$ ./sbt console | |
scala> :load Examples.scala | |
*/ | |
import probability_monad._ | |
import probability_monad.Distribution._ | |
val rushHour: Distribution[Boolean] = tf(0.2) | |
val badWeather: Distribution[Boolean] = tf(0.05) | |
def accident(badWeather: Boolean): Distribution[Boolean] = { | |
badWeather match { | |
case true => tf(0.3) | |
case false => tf(0.1) | |
} | |
} | |
def sirens(accident: Boolean): Distribution[Boolean] = { | |
accident match { | |
case true => tf(0.9) | |
case false => tf(0.2) | |
} | |
} | |
def trafficJam(rushHour: Boolean, | |
badWeather: Boolean, | |
accident: Boolean): Distribution[Boolean] = { | |
(rushHour, badWeather, accident) match { | |
case (true, true, _) => tf(0.95) | |
case (true, _, true) => tf(0.95) | |
case (_, true, true) => tf(0.95) | |
case (true, false, false) => tf(0.5) | |
case (false, true, false) => tf(0.3) | |
case (false, false, true) => tf(0.6) | |
case (false, false, false) => tf(0.1) | |
} | |
} | |
case class Traffic( | |
rushHour: Boolean, | |
badWeather: Boolean, | |
accident: Boolean, | |
sirens: Boolean, | |
trafficJam: Boolean) | |
val traffic: Distribution[Traffic] = for { | |
r <- rushHour | |
w <- badWeather | |
a <- accident(w) | |
s <- sirens(a) | |
t <- trafficJam(r, w, a) | |
} yield Traffic(r, w, a, s, t) | |
sealed trait BloodGene | |
case object A_ extends BloodGene | |
case object B_ extends BloodGene | |
case object O_ extends BloodGene | |
sealed trait BloodType | |
case object A extends BloodType | |
case object B extends BloodType | |
case object AB extends BloodType | |
case object O extends BloodType | |
def typeFromGene(g: (BloodGene, BloodGene)): Distribution[BloodType] = { | |
g match { | |
case (A_, B_) => always(AB) | |
case (B_, A_) => always(AB) | |
case (A_, _) => always(A) | |
case (_, A_) => always(A) | |
case (B_, _) => always(B) | |
case (_, B_) => always(B) | |
case (O_, O_) => always(O) | |
} | |
} | |
def childFromParents(p1: (BloodGene, BloodGene), | |
p2: (BloodGene, BloodGene)): Distribution[(BloodGene, BloodGene)] = { | |
val (p1a, p1b) = p1 | |
val (p2a, p2b) = p2 | |
discreteUniform(for { | |
p1 <- List(p1a, p1b) | |
p2 <- List(p2a, p2b) | |
} yield (p1, p2)) | |
} | |
val bloodPrior: Distribution[(BloodGene, BloodGene)] = { | |
val geneFrequencies = discrete(A_ -> 0.26, B_ -> 0.08, O_ -> 0.66) | |
for { | |
g1 <- geneFrequencies | |
g2 <- geneFrequencies | |
} yield (g1, g2) | |
} | |
case class BloodTrial(lisa: BloodType, homer: BloodType, marge: BloodType, | |
selma: BloodType, jackie: BloodType, harry: BloodType) | |
val bloodType: Distribution[BloodTrial] = for { | |
gHomer <- bloodPrior | |
gHarry <- bloodPrior | |
gJackie <- bloodPrior | |
gSelma <- childFromParents(gHarry, gJackie) | |
gMarge <- childFromParents(gHarry, gJackie) | |
gLisa <- childFromParents(gHomer, gMarge) | |
bLisa <- typeFromGene(gLisa) | |
bHomer <- typeFromGene(gHomer) | |
bMarge <- typeFromGene(gMarge) | |
bSelma <- typeFromGene(gSelma) | |
bJackie <- typeFromGene(gJackie) | |
bHarry <- typeFromGene(gHarry) | |
} yield BloodTrial(bLisa, bHomer, bMarge, bSelma, bJackie, bHarry) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment