📚 The CoCalc Library - books, templates and other resources
License: OTHER
var ARMS = [0,0,0,0,0,0];1var _PROBS = [ rbeta(2,9), rbeta(5,9), rbeta(5,9) ];2var BB_RUN = 0;34d3.select( "#reveal-div" )5.selectAll("p")6.data( _PROBS )7.enter()8.append("p")9.text( function(d,i){ return "Arm " + (i + 1) + ": " +d.toFixed(4); } )101112function pdfbeta(x_array,a,b){13//x is an array14_beta = Beta(a,b);15function _pdfbeta(x){16return ( Math.pow(x,a-1)*Math.pow(1-x, b - 1) )/_beta17}1819return x_array.map( _pdfbeta )20}2122function Beta(a,b){23//stirlings approx24// use logs and exponentials to avoid underflow25// with logs is still giving me errors2627//var n = Math.pow(a, a - 0.5)*Math.pow(b, b-0.5)2829var log_n = Math.log(a)*(a - 0.5) + Math.log(b)*( b-0.5)30//var d = Math.pow( a + b, a+ b-0.5)31var log_d = Math.log( a + b)*(a+ b-0.5)32return Math.sqrt( 2*Math.PI)*Math.exp(log_n - log_d)33}343536function rbeta(a,b){37//from Simulation and MC, Wiley3839var p = a/b;40if (Math.min(a,b) <= 1){41var lambda = Math.min(a,b)42}else{43var lambda = Math.sqrt( (2*a*b - a - b)/(a+b-2) )44}4546while (1){47var R1 = Math.random();48var R2 = Math.random();49var y = Math.pow( ( 1./R1 - 1.), 1./lambda );50if ( 4*R1*R2*R2 < (Math.pow(y, a - lambda)*Math.pow( (1.+ p)/(1 + p*y) , a + b ) )){51return (p*y)/(1+ p*y)52}53}54}5556function rbeta_array( arm_counts){57// to be used with ARMS with uniform prior.58samples = []59for (var i=0; i < arm_counts.length/2; i++){60samples.push(61rbeta(arm_counts[2*i + 1]+1, 1+arm_counts[2*i] - arm_counts[2*i+1] )62)63}64return samples65}6667function draw_arm( p ){68if ( Math.random() < p){ return 1 } else { return 0 }69}707172function update_arm( arm_number ){73var result = draw_arm(_PROBS[arm_number] );74ARMS[2*arm_number] += 1;75ARMS[2*arm_number+1] += result;76redraw(arm_number);77return78}798081function bayesian_bandits(){82//for (var i = 0; i < n_pulls; i++ ){83//sample from Beta distributions84var samples = rbeta_array(ARMS);85var select = samples.indexOf( d3.max( samples) );86update_arm( select );87if (BB_RUN < 300){88BB_RUN += 1;89window.setTimeout( bayesian_bandits, 100 )90}91else{92return93}94//}95}9697var x_array = [];98var _N = 100;99var max_data = 10100for ( var i =0; i < _N; i++ ){101x_array.push( .01*i )102}103104var colors = ["#348ABD", "#A60628", "#7A68A6"];105var fill_colors = [ "rgba(52, 128, 189,0.1)", "rgba(166, 6, 40, 0.1 )", "rgba( 122, 104, 166,0.1 )"];106107var w = 600,108h = 150,109margin = 15,110y = d3.scale.linear().domain([0, max_data]).range([h - margin,0 + margin ]),111x = d3.scale.linear().domain([0,_N]).range([0 + margin, w - margin])112113var vis = d3.select("#beta-graphs")114.append("svg:svg")115.attr("width", w )116.attr("height", h )117118var g = vis.append("svg:g")119120var line = d3.svg.line()121.x(function(d, i) { return x(i); })122.y(y)123124125for ( var i =0; i < 3; i++){126var _data = pdfbeta(x_array, 1 + ARMS[2*i+1],1+ARMS[2*i] - ARMS[2*i+1] );127g.selectAll('path.line')128.data( [_data] )129.enter()130.append("svg:path")131.attr("stroke", colors[i] )132//.attr("fill", fill_colors[i] )133//.attr("fill", fill_colors[i] )134//.attr("stroke-width", 0 )135.attr("d", line )136.attr("id", "line-" + i );137}138139140g.append("svg:line")141.attr("x1", x(0))142.attr("y1", y(0))143.attr("x2", x(w))144.attr("y2", y(0))145146g.append("svg:line")147.attr("x1", x(0))148.attr("y1", y(0))149.attr("x2", x(0))150.attr("y2", y(max_data))151152g.selectAll(".xLabel")153.data( d3.range(0,1.2,.2) )154.enter().append("svg:text")155.attr("class", "xLabel")156.text(String)157.attr("x", function(d) { return x(100*d) })158.attr("y", h)159.attr("text-anchor", "middle")160.attr("dy", 0.0 )161/*162g.selectAll(".yLabel")163.data(y.ticks(4))164.enter().append("svg:text")165.attr("class", "yLabel")166.text(String)167.attr("x", 0)168.attr("y", function(d) { return y(d) })169.attr("text-anchor", "right")170.attr("dy", 4)171*/172g.selectAll(".xTicks")173.data(x.ticks(5))174.enter().append("svg:line")175.attr("class", "xTicks")176.attr("x1", function(d) { return x(d); })177.attr("y1", y(0))178.attr("x2", function(d) { return x(d); })179.attr("y2", y(-0.1))180181vis.append("text")182.attr("x", (w / 2))183.attr("y", 15 )184.attr("text-anchor", "middle")185.style("font-size", "17px")186.text("Posterior Distributions");187188/*189g.selectAll(".yTicks")190.data(y.ticks(4))191.enter().append("svg:line")192.attr("class", "yTicks")193.attr("y1", function(d) { return -1 * y(d); })194.attr("x1", x(-0.3))195.attr("y2", function(d) { return -1 * y(d); })196.attr("x2", x(0))197*/198199200201202<!-- Data for bar chart: Two time-series, alternating to form a single series. Bar Color will switch back & forth -->203204var data = ARMS;205var labellist = ["Arm 1", "", "Arm 2", "", "Arm 3", ""];206207var w_bar = 600,208h_bar = 170,209labelpad = 50,210x_bar = d3.scale.linear().domain([0, 100]).range([0, w_bar]),211y_bar = d3.scale.ordinal().domain(d3.range(data.length)).rangeBands([0, h_bar], .2);212213var vis = d3.select("#paired-bar-chart")214.append("svg:svg")215.attr("width", w_bar + 40)216.attr("height", h_bar + 20)217.append("svg:g")218219var bars = vis.selectAll("g.bar")220.data(data)221.enter().append("svg:g")222.attr("class", "bar")223.attr("transform", function(d, i) { return "translate(" + labelpad + "," + y_bar(i) + ")"; })224225226bars.append("svg:rect")227.attr("fill", function(d, i) { return (i%2)? colors[i]: fill_colors[i]; } ) //Alternate colors228.attr("width", function(d,i){ return x_bar(d)*0.5 })229.attr("height", y_bar.rangeBand());230231bars.append("svg:text")232.attr("x", 0)233.attr("y", 10 + y_bar.rangeBand() / 2)234.attr("dx", -6)235.attr("dy", ".50em")236.attr("text-anchor", "end")237.text(function(d, i) { return labellist[i]; });238239var counts = bars.append("svg:text")240.attr("x", 0)241.attr("y", 10 + y_bar.rangeBand() / 2)242.attr("dx", -6)243.attr("dy", "-.40em")244.attr("text-anchor", "end")245.text(function(d, i) { return ""; });246247248var rules = vis.selectAll("g.rule")249.data(x.ticks(10))250.enter().append("svg:g")251.attr("class", "rule")252.attr("transform", function(d) { return "translate(" + x_bar(d) + ", 0)"; });253254255rules.append("svg:line")256.attr("y1", 0)257.attr("y2", h_bar)258.attr("x1", labelpad)259.attr("x2", labelpad)260.attr("stroke", "white")261.attr("stroke-opacity", .3);262263264265function redraw(arm_number){266267var _data = []268for ( var i =0; i < 3; i++){269_data.push( pdfbeta(x_array, 1 + ARMS[2*i+1],1+ARMS[2*i] - ARMS[2*i+1] ) );270271}272//update what is max.273max_data = d3.max( [27410,275d3.max(_data[0]),276d3.max(_data[1]),277d3.max(_data[2]) ])278279y = d3.scale.linear().domain([0, max_data]).range([h - margin,0 + margin ])280line = d3.svg.line()281.x(function(d, i) { return x(i); })282.y(y)283284for ( var i =0; i < 3; i++){285g.select("#line-" + i)286.data( [_data[i]] )287.attr("d", line )288}289290291292293294295bars.data(ARMS)296.enter().append("svg:g")297.attr("class", "bar")298.attr("transform", function(d, i) { return "translate(" + labelpad + "," + y(i) + ")"; });299300301bars.append("svg:rect")302.attr("fill", function(d, ix) {_ix = Math.floor(ix/2); return (ix%2)? fill_colors[_ix]: colors[_ix]; } ) //Alternate colors303.attr("width", function(d,i){ return x_bar(d)*0.5 })304.attr("height", y_bar.rangeBand());305306307counts308.attr("x", 0)309.attr("y", 10 + y_bar.rangeBand() / 2)310.attr("dx", function( d,i) { return !(i%2) ? 50 + 3.2*data[i] : 67 + 3.2*data[i] ;})311.attr("dy", "-.40em")312.attr("text-anchor", "end")313.text(function(d, i) { return !(i%2) ? data[i] + " pulls" : data[i] + " rewards" ;});314315//update scoreboard316var rewards = ARMS[1] + ARMS[3] + ARMS[5];317var pulls = ARMS[0] + ARMS[2] + ARMS[4];318document.getElementById("rewards").innerHTML = rewards ;319document.getElementById("pulls").innerHTML = pulls ;320document.getElementById("ratio").innerHTML = (rewards/pulls).toFixed(3) ;321322}323324325d3.select( "#reveal-div" )326.selectAll("p")327.data( _PROBS )328.enter()329.append("span")330.attr( "style", "margin-left:15; margin-right: 30px; margin-top:0" )331.text( function(d,i){ return d.toFixed(4) ; } )332//redraw() //to initialize333334335