Last active
July 20, 2018 18:13
-
-
Save rlbarter/0d0d5aaaa5008718002cd942f6e63a00 to your computer and use it in GitHub Desktop.
Bayesian
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<head> | |
<meta charset="utf-8"> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<script src="https://d3js.org/d3-random.v1.min.js"></script> | |
<script src="https://peterbeshai.com/d3-interpolate-path/d3-interpolate-path.js"></script> | |
<style> | |
text { | |
font-size: 14px; | |
font-family: avenir; | |
} | |
</style> | |
</head> | |
<body> | |
<script> | |
var margin = {top: 20, right: 10, bottom: 20, left: 10}; | |
var width = 900 - margin.left - margin.right, | |
height = 1000 - margin.top - margin.bottom; | |
var svg = d3.select("body").append("svg") | |
.attr("width", width + margin.left + margin.right) | |
.attr("height", height + margin.top + margin.bottom) | |
.append("g") | |
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | |
var color = d3.scaleOrdinal(d3.schemeCategory10); | |
var y_2 = 300; | |
var y_1 = 150; | |
var y_3 = 500; | |
var iteration = 0; | |
var point_opacity = 0.6; | |
var newkernelpath = []; | |
var x = d3.scaleLinear() | |
.domain([-4, 4]) | |
.range([margin.left + 200, width - margin.right - 200]); | |
var y = d3.scaleLinear() | |
.domain([0, 0.05]) | |
.range([y_1, y_1 + 20]); | |
var y_kernel = d3.scaleLinear() | |
.domain([0, 0.05]) | |
.range([y_3 + 1, y_3]); | |
var density_data = [-3, -2.99, -2.98, -2.97, -2.96, -2.95, -2.94, -2.93, -2.92, -2.91, -2.9, -2.89, -2.88, -2.87, -2.86, -2.85, -2.84, -2.83, -2.82, -2.81, -2.8, -2.79, -2.78, -2.77, -2.76, -2.75, -2.74, -2.73, -2.72, -2.71, -2.7, -2.69, -2.68, -2.67, -2.66, -2.65, -2.64, -2.63, -2.62, -2.61, -2.6, -2.59, -2.58, -2.57, -2.56, -2.55, -2.54, -2.53, -2.52, -2.51, -2.5, -2.49, -2.48, -2.47, -2.46, -2.45, -2.44, -2.43, -2.42, -2.41, -2.4, -2.39, -2.38, -2.37, -2.36, -2.35, -2.34, -2.33, -2.32, -2.31, -2.3, -2.29, -2.28, -2.27, -2.26, -2.25, -2.24, -2.23, -2.22, -2.21, -2.2, -2.19, -2.18, -2.17, -2.16, -2.15, -2.14, -2.13, -2.12, -2.11, -2.1, -2.09, -2.08, -2.07, -2.06, -2.05, -2.04, -2.03, -2.02, -2.01, -2, -1.99, -1.98, -1.97, -1.96, -1.95, -1.94, -1.93, -1.92, -1.91, -1.9, -1.89, -1.88, -1.87, -1.86, -1.85, -1.84, -1.83, -1.82, -1.81, -1.8, -1.79, -1.78, -1.77, -1.76, -1.75, -1.74, -1.73, -1.72, -1.71, -1.7, -1.69, -1.68, -1.67, -1.66, -1.65, -1.64, -1.63, -1.62, -1.61, -1.6, -1.59, -1.58, -1.57, -1.56, -1.55, -1.54, -1.53, -1.52, -1.51, -1.5, -1.49, -1.48, -1.47, -1.46, -1.45, -1.44, -1.43, -1.42, -1.41, -1.4, -1.39, -1.38, -1.37, -1.36, -1.35, -1.34, -1.33, -1.32, -1.31, -1.3, -1.29, -1.28, -1.27, -1.26, -1.25, -1.24, -1.23, -1.22, -1.21, -1.2, -1.19, -1.18, -1.17, -1.16, -1.15, -1.14, -1.13, -1.12, -1.11, -1.1, -1.09, -1.08, -1.07, -1.06, -1.05, -1.04, -1.03, -1.02, -1.01, -1, -0.99, -0.98, -0.97, -0.96, -0.95, -0.94, -0.93, -0.92, -0.91, -0.9, -0.89, -0.88, -0.87, -0.86, -0.85, -0.84, -0.83, -0.82, -0.81, -0.8, -0.79, -0.78, -0.77, -0.76, -0.75, -0.74, -0.73, -0.72, -0.71, -0.7, -0.69, -0.68, -0.67, -0.66, -0.65, -0.64, -0.63, -0.62, -0.61, -0.6, -0.59, -0.58, -0.57, -0.56, -0.55, -0.54, -0.53, -0.52, -0.51, -0.5, -0.49, -0.48, -0.47, -0.46, -0.45, -0.44, -0.43, -0.42, -0.41, -0.4, -0.39, -0.38, -0.37, -0.36, -0.35, -0.34, -0.33, -0.32, -0.31, -0.3, -0.29, -0.28, -0.27, -0.26, -0.25, -0.24, -0.23, -0.22, -0.21, -0.2, -0.19, -0.18, -0.17, -0.16, -0.15, -0.14, -0.13, -0.12, -0.11, -0.1, -0.0899999999999999, -0.0800000000000001, -0.0699999999999998, -0.0600000000000001, -0.0499999999999998, -0.04, -0.0299999999999998, -0.02, -0.00999999999999979, 0, 0.0100000000000002, 0.02, 0.0300000000000002, 0.04, 0.0500000000000003, 0.0600000000000001, 0.0700000000000003, 0.0800000000000001, 0.0899999999999999, 0.1, 0.11, 0.12, 0.13, 0.14, 0.15, 0.16, 0.17, 0.18, 0.19, 0.2, 0.21, 0.22, 0.23, 0.24, 0.25, 0.26, 0.27, 0.28, 0.29, 0.3, 0.31, 0.32, 0.33, 0.34, 0.35, 0.36, 0.37, 0.38, 0.39, 0.4, 0.41, 0.42, 0.43, 0.44, 0.45, 0.46, 0.47, 0.48, 0.49, 0.5, 0.51, 0.52, 0.53, 0.54, 0.55, 0.56, 0.57, 0.58, 0.59, 0.6, 0.61, 0.62, 0.63, 0.64, 0.65, 0.66, 0.67, 0.68, 0.69, 0.7, 0.71, 0.72, 0.73, 0.74, 0.75, 0.76, 0.77, 0.78, 0.79, 0.8, 0.81, 0.82, 0.83, 0.84, 0.85, 0.86, 0.87, 0.88, 0.89, 0.9, 0.91, 0.92, 0.93, 0.94, 0.95, 0.96, 0.97, 0.98, 0.99, 1, 1.01, 1.02, 1.03, 1.04, 1.05, 1.06, 1.07, 1.08, 1.09, 1.1, 1.11, 1.12, 1.13, 1.14, 1.15, 1.16, 1.17, 1.18, 1.19, 1.2, 1.21, 1.22, 1.23, 1.24, 1.25, 1.26, 1.27, 1.28, 1.29, 1.3, 1.31, 1.32, 1.33, 1.34, 1.35, 1.36, 1.37, 1.38, 1.39, 1.4, 1.41, 1.42, 1.43, 1.44, 1.45, 1.46, 1.47, 1.48, 1.49, 1.5, 1.51, 1.52, 1.53, 1.54, 1.55, 1.56, 1.57, 1.58, 1.59, 1.6, 1.61, 1.62, 1.63, 1.64, 1.65, 1.66, 1.67, 1.68, 1.69, 1.7, 1.71, 1.72, 1.73, 1.74, 1.75, 1.76, 1.77, 1.78, 1.79, 1.8, 1.81, 1.82, 1.83, 1.84, 1.85, 1.86, 1.87, 1.88, 1.89, 1.9, 1.91, 1.92, 1.93, 1.94, 1.95, 1.96, 1.97, 1.98, 1.99, 2, 2.01, 2.02, 2.03, 2.04, 2.05, 2.06, 2.07, 2.08, 2.09, 2.1, 2.11, 2.12, 2.13, 2.14, 2.15, 2.16, 2.17, 2.18, 2.19, 2.2, 2.21, 2.22, 2.23, 2.24, 2.25, 2.26, 2.27, 2.28, 2.29, 2.3, 2.31, 2.32, 2.33, 2.34, 2.35, 2.36, 2.37, 2.38, 2.39, 2.4, 2.41, 2.42, 2.43, 2.44, 2.45, 2.46, 2.47, 2.48, 2.49, 2.5, 2.51, 2.52, 2.53, 2.54, 2.55, 2.56, 2.57, 2.58, 2.59, 2.6, 2.61, 2.62, 2.63, 2.64, 2.65, 2.66, 2.67, 2.68, 2.69, 2.7, 2.71, 2.72, 2.73, 2.74, 2.75, 2.76, 2.77, 2.78, 2.79, 2.8, 2.81, 2.82, 2.83, 2.84, 2.85, 2.86, 2.87, 2.88, 2.89, 2.9, 2.91, 2.92, 2.93, 2.94, 2.95, 2.96, 2.97, 2.98, 2.99, 3]; | |
// AXES ////////////////////////////////////////////////////////////////// | |
// add horizontal lines for parameter space | |
svg.selectAll("thetaspace") | |
.data([0]) | |
.enter() | |
.append("line") | |
.attr("x1", margin.left + 200) | |
.attr("x2", margin.left + width - 200) | |
.attr("y1", y_1) | |
.attr("y2", y_1) | |
.attr("stroke", "grey") | |
svg.selectAll("paramtext") | |
.data(["parameter space"]) | |
.enter() | |
.append("text") | |
.attr("x", margin.left + width - 180) | |
.attr("y", y_1 + 5) | |
.attr("fill", "black") | |
.attr("text-anchor", "left") | |
.html(function(d) { return d; }) | |
.style("font-size", "20px"); | |
// add horizontal lines for data space | |
svg.selectAll("dataspace") | |
.data([0]) | |
.enter() | |
.append("line") | |
.attr("x1", margin.left + 200) | |
.attr("x2", margin.left + width - 200) | |
.attr("y1", y_2) | |
.attr("y2", y_2) | |
.attr("stroke", "grey") | |
svg.selectAll("datatext") | |
.data(["data space"]) | |
.enter() | |
.append("text") | |
.attr("x", margin.left + width - 180) | |
.attr("y", y_2 + 5) | |
.attr("fill", "black") | |
.attr("text-anchor", "left") | |
.html(function(d) { return d; }) | |
.style("font-size", "20px"); | |
// add horizontal lines for estimator space | |
svg.selectAll("estspace") | |
.data([0]) | |
.enter() | |
.append("line") | |
.attr("x1", margin.left + 200) | |
.attr("x2", margin.left + width - 200) | |
.attr("y1", y_3) | |
.attr("y2", y_3) | |
.attr("stroke", "grey") | |
svg.selectAll("esttext") | |
.data(["estimator space"]) | |
.enter() | |
.append("text") | |
.attr("x", margin.left + width - 180) | |
.attr("y", y_3 + 5) | |
.attr("fill", "black") | |
.attr("text-anchor", "left") | |
.html(function(d) { return d; }) | |
.style("font-size", "20px"); | |
// Place theta /////////////////////////////////////////////////////////// | |
// Add theta at top | |
var x_theta = d3.randomNormal(0, 1)(1); | |
d3.select("body").on("click", function() { | |
svg.append("path") | |
.attr("d", axisLineFunction(density_data)) | |
.attr("fill", "none") | |
.attr("stroke", "grey") | |
.attr("stroke-linejoin", "round") | |
.transition() | |
.duration(1000) | |
.attrTween('d', function () { | |
return d3.interpolatePath(axisLineFunction(density_data), | |
densityLineFunction(density_data)); | |
}); | |
// add normal density | |
d3.select("body").on("click", function() { | |
svg.append("text") | |
.attr("x", x(x_theta)) | |
.attr("y", y_1 - 10) | |
.attr("fill", "black") | |
.attr("text-anchor", "middle") | |
.html("θ") | |
.style("font-size", "34px"); | |
svg.append("circle") | |
.attr("cx", x(x_theta)) | |
.attr("cy", y_1) | |
.attr("fill", "black") | |
.attr("r", 4); | |
// add first set of data points | |
d3.select("body").on("click", function() { | |
// define the random data | |
var data = d3.range(10).map(function() { | |
return d3.randomNormal(x_theta, 1)(1); | |
}); | |
var lines = svg.selectAll("firstline") | |
.data(data) | |
.enter() | |
.append("line") | |
.attr("x1", x(x_theta)) | |
.attr("y1", y_1 + 10) | |
.attr("x2", x(x_theta)) | |
.attr("y2", y_1 + 10) | |
.attr("stroke", color(iteration)) | |
.transition() | |
.duration(1000) | |
.delay(function(d, i) { return i * 100}) | |
.attr("x2", function(d) { return x(d); }) | |
.attr("y2", y_2) | |
.attr("stroke-width", 2) | |
.attr("opacity", 1); | |
var circleborder = svg.selectAll("datacircle") | |
.data(data) | |
.enter() | |
.append("circle") | |
.attr("r", 0) | |
.attr("cx", function(d) { return x(d); }) | |
.attr("cy", y_2) | |
.attr("fill", "white") | |
.transition() | |
.delay(function(d, i) { return i * 100 + 800; }) | |
.duration(200) | |
.attr("r", 13); | |
var circles = svg.selectAll("datacircle") | |
.data(data) | |
.enter() | |
.append("circle") | |
.attr("r", 0) | |
.attr("cx", function(d) { return x(d); }) | |
.attr("cy", y_2) | |
.attr("fill", color(iteration)) | |
.transition() | |
.delay(function(d, i) { return i * 100 + 800; }) | |
.duration(200) | |
.attr("r", 10) | |
.attr("opacity", 1); | |
var meancircles = svg.selectAll("datacircle") | |
.data(data) | |
.enter() | |
.append("circle") | |
.attr("r", 0) | |
.attr("cx", function(d) { return x(d); }) | |
.attr("cy", y_2) | |
.attr("fill", color(iteration)) | |
.transition() | |
.duration(800) | |
.delay(function(d, i) { return 2000; }) | |
.attr("cx", x(d3.mean(data))) | |
.attr("cy", y_3) | |
.attr("fill", color(iteration)) | |
.attr("r", 9); | |
var mean_data = [d3.mean(data), d3.mean(data)]; | |
var kernel = kernelDensityEstimator(kernelEpanechnikov(1), x.ticks(20))(mean_data); | |
var kernelpath = svg.append("path") | |
.attr("d", y3axisLineFunction(density_data)) | |
.attr("fill", "none") | |
.attr("stroke", "grey") | |
.attr("stroke-linejoin", "round") | |
.transition() | |
.delay(2000) | |
.duration(2000) | |
.attrTween('d', function () { | |
return d3.interpolatePath(y3axisLineFunction(density_data), | |
kernelLineFunction(kernel)); | |
}); | |
newkernelpath[0] = kernelpath; | |
// add first set of data points | |
d3.select("body").on("click", function() { | |
iteration = iteration + 1; | |
var x_theta_new = d3.randomNormal(0, 1)(1); | |
svg.append("text") | |
.attr("x", x(x_theta_new)) | |
.attr("y", y_1 - 10) | |
.attr("fill", color(iteration)) | |
.attr("text-anchor", "middle") | |
.html("θ") | |
.style("font-size", "34px"); | |
svg.append("circle") | |
.attr("cx", x(x_theta_new)) | |
.attr("cy", y_1) | |
.attr("fill", color(iteration)) | |
.attr("r", 4); | |
// define the random data | |
var datanew = d3.range(10).map(function() { | |
return d3.randomNormal(x_theta_new, 1)(1); | |
}); | |
var lines = svg.selectAll("firstline") | |
.data(datanew) | |
.enter() | |
.append("line") | |
.attr("x1", x(x_theta_new)) | |
.attr("y1", y_1 + 10) | |
.attr("x2", x(x_theta_new)) | |
.attr("y2", y_1 + 10) | |
.attr("stroke", color(iteration)) | |
.transition() | |
.duration(1000) | |
.delay(function(d, i) { return i * 100}) | |
.attr("x2", function(d) { return x(d); }) | |
.attr("y2", y_2) | |
.attr("stroke-width", 2) | |
.attr("opacity", point_opacity) | |
.transition() | |
.duration(2000) | |
.delay(function(d, i) { return 1500 - i * 100; }) | |
.attr("opacity", 0); | |
var circleborder = svg.selectAll("datacircle") | |
.data(datanew) | |
.enter() | |
.append("circle") | |
.attr("r", 0) | |
.attr("cx", function(d) { return x(d); }) | |
.attr("cy", y_2) | |
.attr("fill", "white") | |
.transition() | |
.delay(function(d, i) { return i * 100 + 800; }) | |
.duration(200) | |
.attr("r", 13) | |
.attr("opacity", point_opacity) | |
.transition() | |
.duration(2000) | |
.delay(function(d, i) { return 1500 - i * 100; }) | |
.attr("opacity", 0); | |
var circles = svg.selectAll("datacircle") | |
.data(datanew) | |
.enter() | |
.append("circle") | |
.attr("r", 0) | |
.attr("cx", function(d) { return x(d); }) | |
.attr("cy", y_2) | |
.attr("fill", color(iteration)) | |
.transition() | |
.delay(function(d, i) { return i * 100 + 800; }) | |
.duration(200) | |
.attr("r", 10) | |
.attr("opacity", point_opacity) | |
.transition() | |
.duration(2000) | |
.delay(function(d, i) { return 1500 - i * 100; }) | |
.attr("opacity", 0); | |
var newmeancircles = svg.selectAll("newmeancircle") | |
.data(datanew) | |
.enter() | |
.append("circle") | |
.attr("r", 0) | |
.attr("cx", function(d) { return x(d); }) | |
.attr("cy", y_2) | |
.attr("fill", color(iteration)) | |
.attr("opacity", 0.3) | |
.transition() | |
.duration(800) | |
.delay(2000) | |
.attr("cx", x(d3.mean(datanew))) | |
.attr("cy", y_3) | |
.attr("r", 7) | |
.attr("opacity", 0.1); | |
var old_kernel = kernelDensityEstimator(kernelEpanechnikov(1), x.ticks(20))(mean_data); | |
mean_data.push(d3.mean(datanew)); | |
var kernel = kernelDensityEstimator(kernelEpanechnikov(1), x.ticks(20))(mean_data); | |
// hacky way to get the kernel path to update at each iteration | |
newkernelpath[iteration] = newkernelpath[iteration - 1].transition() | |
.delay(1500) | |
.duration(2000) | |
.attrTween('d', function () { | |
return d3.interpolatePath(kernelLineFunction(old_kernel), | |
kernelLineFunction(kernel)); | |
}); | |
}); | |
}); | |
}); | |
}); | |
// Normal distribution function //////////////////////////////////////////// | |
var densityLineFunction = d3.line() | |
.curve(d3.curveBasis) | |
.x(function(d) { return x(d); }) | |
.y(function(d) { return y(normalFun(d)); }); | |
var normalFun = function(x) { | |
return (-(1 / Math.sqrt(Math.PI * 2)) * Math.exp(- 0.5 * Math.pow(x, 2))); | |
} | |
var axisLineFunction = d3.line() | |
.x(function(d) { return x(d); }) | |
.y(y_1); | |
var y3axisLineFunction = d3.line() | |
.x(function(d) { return x(d); }) | |
.y(y_3); | |
// Density function ////////////////////////////////////////////////////////// | |
function kernelDensityEstimator(kernel, X) { | |
return function(V) { | |
return X.map(function(x) { | |
return [x, 10 * d3.mean(V, function(v) { return kernel(x - v); })]; | |
}); | |
}; | |
} | |
function kernelEpanechnikov(k) { | |
return function(v) { | |
return Math.abs(v /= k) <= 1 ? 0.75 * (1 - v * v) / k : 0; | |
}; | |
} | |
var kernelLineFunction = d3.line() | |
.curve(d3.curveBasis) | |
.x(function(d) { return x(d[0]); }) | |
.y(function(d) { return y_kernel(d[1]); }); | |
</script> | |
</body> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment