Bayes learning simulation
- random variable x under Gaussian distribution
- u is unknown, σ is known
- p(x | u) ~ N(u, σσ)
- goal: guess u, the real mean, using Bayes parameter estimation
- assume p(u) ~ N(u0, σ0σ0)
- u0: our best guess for u
- σ0σ0: uncertainty about u0
- uN: best guess for u, given N samples
- σNσN: uncertainty about uN
experiment
- set u, u0, σ0 with random values
- at each frame...
- N increases
- simulate sample mean
- calculate uN and σN
- render our guess (red line is the real mean)
reference: Richard O. Duda. Chapter 3: MLE and Bayesian Estimation In Pattern Classification 2ed (pp. 11-13).
/**
* Copyright wrotenodoc ( http://wonderfl.net/user/wrotenodoc )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/4NX9
*/
package {
import flash.events.Event
import flash.display.Graphics
import flash.display.Shape
import flash.display.Sprite
import flash.text.TextField
public class BayesLearningSimulation extends Sprite {
private var debug:TextField
private var graph:Shape
private var realMean:Number
private var realStdDev:Number = 30
private var N:int = 0
private const root_2pi_dev:Number = 1 / Math.sqrt(2*Math.PI)
private var samplesAccum:Number
private var guessMean0:Number
private var guessStdDev0:Number
public function BayesLearningSimulation() {
// write as3 code here..
debug = new TextField
debug.text = "click to restart"
debug.autoSize = "left"
addChild(debug)
addChild(graph = new Shape)
graph.x = stage.stageWidth * .5
graph.y = stage.stageHeight * 0.8
init()
addEventListener("enterFrame", loop)
stage.addEventListener("mouseDown", init)
}
private function loop(e:Event):void {
N++
var rand:Number = Math.random()
var dir:Number = Math.random() < .5 ? -1 : 1
samplesAccum += realMean + dir * Math.sqrt(-2*realStdDev*realStdDev*Math.log(root_2pi_dev * rand))
var sampleMean:Number = samplesAccum / N
var s0s0:Number = guessStdDev0 * guessStdDev0
var ns0s0:Number = N * s0s0
var ss:Number = realStdDev * realStdDev
var guessMeanN:Number = (ns0s0 / (ns0s0 + ss))*sampleMean + (ss / (ns0s0 + ss)) * guessMean0
var guessStdDevN:Number = (s0s0 * ss) / (N*s0s0 + ss)
graph.graphics.clear()
graph.graphics.lineStyle(1, 0xff0000)
graph.graphics.moveTo(realMean, 0)
graph.graphics.lineTo(realMean, -stage.stageHeight)
debug.text = "real mean: " + realMean + "\nguess mean: " + guessMeanN + "\nclick to restart"
render(guessMeanN, guessStdDevN)
}
private function init(e:Event=null):void {
N = 0
samplesAccum = 0
realMean = (Math.random() - .5) * stage.stageWidth
guessMean0 = (Math.random() - .5) * stage.stageWidth
guessStdDev0 = 10 + Math.random() * 100
}
private function render(mean:Number, std_deviation:Number):void {
var g:Graphics = graph.graphics
g.lineStyle(0, 0x0)
g.moveTo(-stage.stageWidth/2, 0)
g.lineTo(stage.stageWidth/2, 0)
var x:Number = -stage.stageWidth/2
var fx:Number = Math.exp(-.5 * z) / 1000
g.moveTo(x, fx)
for(; x<=stage.stageWidth/2; x++){
var z:Number = (x - mean) / std_deviation
fx = 1/(Math.sqrt(2*Math.PI*std_deviation)) * Math.exp(-.5 * z*z) * 1000
g.lineTo(x, -fx)
}
}
}
}