Skip to content

Commit

Permalink
Merge pull request #495 from gtakata/DEV3.2.1.1
Browse files Browse the repository at this point in the history
Add DataReduction methods to reduce distribution
  • Loading branch information
mreposa committed Jul 8, 2015
2 parents 32e6cd0 + 3ea993a commit e6bb2c4
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import com.cra.figaro.language.{Element}
import com.cra.figaro.util.visualization.results.{ ContinuousData, DiscreteData, ResultsData, ResultsTable, ResultsView }
import com.cra.figaro.util.visualization.histogram.{ Histogram }
import com.cra.figaro.util.visualization.distribution.{Distribution}
import com.cra.figaro.util.visualization.reduction.DataReduction
import com.cra.figaro.util.ColorGradient
import scala.swing.event.Event
import scala.swing.event.TableRowsSelected
Expand All @@ -42,17 +43,17 @@ class EmptyTab extends BoxPanel(Orientation.Vertical) {
}

object ResultsGUI extends SimpleSwingApplication {
val TAB_WIDTH = 400
val TAB_WIDTH = 600
val TAB_HEIGHT = 300

val TABLE_WIDTH = 400
val TABLE_WIDTH = 600
val TABLE_HEIGHT = 250

val results = new ResultHandler
// def addResult(result: ResultsData) {
def addResult(name: String, dist: Any) {
val result = dist match {
case l: List[(Double, _)] => DiscreteData(name, l)
case l: List[(Double, Double)] => DiscreteData(name, DataReduction.binToDistribution(l))
case e: Element[_] => ContinuousData(name, e)
}
results.newResult(result)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,30 +72,24 @@ class Distribution(val dataview: DataView, var color: String) extends BorderPane
// dynamic query based on name
val valueQ: RangeQueryBinding = new RangeQueryBinding(visualTable, "Value");
val filter: AndPredicate = new AndPredicate(valueQ.getPredicate());
val nf = NumberFormat.getIntegerInstance();
nf.setMaximumFractionDigits(2);

// X-axis
val xaxis: AxisLayout = new AxisLayout(dataview.name, "Value", Constants.X_AXIS, VisiblePredicate.TRUE);

// ensure the axis spans the width of the data container
// xaxis.setDataType(Constants.NOMINAL)
// xaxis.setRangeModel(dataview.range)

// add the labels to the x-axis
val xlabels: AxisLabelLayout = new AxisLabelLayout("xlab", xaxis);
val xlabels: AxisLabelLayout = new AxisLabelLayout("xlab", xaxis)
xlabels.setNumberFormat(nf)
vis.putAction("xlabels", xlabels)

// Y-axis
val yaxis: AxisLayout = new AxisLayout(dataview.name, "Probability", Constants.Y_AXIS, VisiblePredicate.TRUE);

// ensure the y-axis spans the height of the data container

// set the y-axis range
// val rangeModel = new NumberRangeModel(0, .25, 0, .25);
yaxis.setRangeModel(dataview.yRangeModel)
// add the labels to the y-axis
val ylabels: AxisLabelLayout = new AxisLabelLayout("ylab", yaxis);
val nf = NumberFormat.getIntegerInstance();
nf.setMaximumFractionDigits(2);
ylabels.setNumberFormat(nf);

// drawing actions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ class Histogram(val dataview: DataView, var color: String) extends BorderPanel {
// dynamic query based on name
val valueQ: RangeQueryBinding = new RangeQueryBinding(visualTable, "Value");
val filter: AndPredicate = new AndPredicate(valueQ.getPredicate());
val nf = NumberFormat.getIntegerInstance();
nf.setMaximumFractionDigits(2);

// X-axis
val xaxis: AxisLayout = new AxisLayout(dataview.name, "Value", Constants.X_AXIS, VisiblePredicate.TRUE);
Expand All @@ -82,19 +84,16 @@ class Histogram(val dataview: DataView, var color: String) extends BorderPanel {

// add the labels to the x-axis
val xlabels: AxisLabelLayout = new AxisLabelLayout("xlab", xaxis);
xlabels.setNumberFormat(nf)
vis.putAction("xlabels", xlabels)

// Y-axis
val yaxis: AxisLayout = new AxisLayout(dataview.name, "Probability", Constants.Y_AXIS, VisiblePredicate.TRUE);

// ensure the y-axis spans the height of the data container

// set the y-axis range
yaxis.setRangeModel(dataview.yRangeModel)
// add the labels to the y-axis
val ylabels: AxisLabelLayout = new AxisLabelLayout("ylab", yaxis);
val nf = NumberFormat.getIntegerInstance();
nf.setMaximumFractionDigits(2);
ylabels.setNumberFormat(nf);

// drawing actions
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.cra.figaro.util.visualization.reduction

import scala.collection._

/**
* @author gtakata
*/
object DataReduction {
def binToDistribution(data: List[(Double, Double)]): List[(Double, Double)] = {
if (data.size > 50) {
var mean = 0.0
var totalProb = 0.0
var count = 0
var min = Double.MaxValue
var max = Double.MinValue
var ss = 0.0

for ((prob, value) <- data) {
totalProb += prob
mean += prob * value
min = math.min(min, value)
max = math.max(max, value)
ss += prob * value * value
count += 1
}

val variance = ss - mean * mean
val sd = math.sqrt(variance)

val distMax = mean + 3 * sd
val distMin = mean - 3 * sd

val nInterval = math.min(count, 300)
val interval = (distMax - distMin) / nInterval
var dist = Array.fill[Double](nInterval)(0)

for ((prob, value) <- data) {
val pos = math.max(math.min(math.floor((value - distMin) / interval).toInt, nInterval - 1), 0)
val posProb = dist(pos)
dist(pos) = posProb + prob
}

val probDist = for (i <- 1 to nInterval) yield {
val value = distMin + i * interval
(dist(i - 1), value)
}

probDist.toList
} else {
data
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,17 @@ class ResultsView[T](data: ResultsData) extends DataView {
}
}

def yMax = data.distribution.reduceLeft((a, b) => if (a._1 > b._1) a else b)._1
def yMax = math.min(1.1 * data.distribution.reduceLeft((a, b) => if (a._1 > b._1) a else b)._1, 1.0)
def yRangeModel = {
data match {
case ContinuousData(_, _) => {
new NumberRangeModel(0, 1.1 * yMax, 0, 1.1 * yMax )
case ContinuousData(_, _) =>
new NumberRangeModel(0, yMax, 0, yMax )
case _ => {
if (yMax < 0.5)
new NumberRangeModel(0, yMax, 0, yMax)
else
new NumberRangeModel(0, 1.0, 0, 1.0)
}
case _ => new NumberRangeModel(0, 1.0, 0, 1.0)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
*
* See http://www.github.com/p2t2/figaro for a copy of the software license.
*/

package com.cra.figaro.example.visualization

import com.cra.figaro.algorithm.factored._
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Regression.scala
* A Bayesian network example with visualization
*
* Created By: Glenn Takata (gtakata@cra.com)
* Creation Date: Jul 7, 2015
*
* Copyright 2015 Avrom J. Pfeffer and Charles River Analytics, Inc.
* See http://www.cra.com or email figaro@cra.com for information.
*
* See http://www.github.com/p2t2/figaro for a copy of the software license.
*/
package com.cra.figaro.example.visualization

import com.cra.figaro.language.{Universe}
import com.cra.figaro.algorithm.sampling.{Importance}
import com.cra.figaro.library.atomic.continuous.{Normal, Uniform}
import com.cra.figaro.util.visualization.ResultsGUI

/**
* @author Glenn Takata (gtakata@cra.com)
*/
object Regression {
Universe.createNew()

private val mean = Uniform(0, 1)

for (_ <- 0 until 100) {
val n = Normal(mean, 1.0)
n.addConstraint((m: Double) => m + 5)
}


def main(args: Array[String]) {
val gui = ResultsGUI
gui.startup(args)

val alg = Importance(1000, mean)
alg.start()

val dist = alg.distribution(mean)
println("Probability of mean: " + dist.toList)

gui.addResult("mean", alg.distribution(mean).toList)

alg.kill
}
}

0 comments on commit e6bb2c4

Please sign in to comment.