Contact
CoCalc Logo Icon
StoreFeaturesDocsShareSupport News AboutSign UpSign In
| Download
Views: 3195
1
var ARMS = [0,0,0,0,0,0];
2
var _PROBS = [ rbeta(2,9), rbeta(5,9), rbeta(5,9) ];
3
var BB_RUN = 0;
4
5
d3.select( "#reveal-div" )
6
.selectAll("p")
7
.data( _PROBS )
8
.enter()
9
.append("p")
10
.text( function(d,i){ return "Arm " + (i + 1) + ": " +d.toFixed(4); } )
11
12
13
function pdfbeta(x_array,a,b){
14
//x is an array
15
_beta = Beta(a,b);
16
function _pdfbeta(x){
17
return ( Math.pow(x,a-1)*Math.pow(1-x, b - 1) )/_beta
18
}
19
20
return x_array.map( _pdfbeta )
21
}
22
23
function Beta(a,b){
24
//stirlings approx
25
// use logs and exponentials to avoid underflow
26
// with logs is still giving me errors
27
28
//var n = Math.pow(a, a - 0.5)*Math.pow(b, b-0.5)
29
30
var log_n = Math.log(a)*(a - 0.5) + Math.log(b)*( b-0.5)
31
//var d = Math.pow( a + b, a+ b-0.5)
32
var log_d = Math.log( a + b)*(a+ b-0.5)
33
return Math.sqrt( 2*Math.PI)*Math.exp(log_n - log_d)
34
}
35
36
37
function rbeta(a,b){
38
//from Simulation and MC, Wiley
39
40
var p = a/b;
41
if (Math.min(a,b) <= 1){
42
var lambda = Math.min(a,b)
43
}else{
44
var lambda = Math.sqrt( (2*a*b - a - b)/(a+b-2) )
45
}
46
47
while (1){
48
var R1 = Math.random();
49
var R2 = Math.random();
50
var y = Math.pow( ( 1./R1 - 1.), 1./lambda );
51
if ( 4*R1*R2*R2 < (Math.pow(y, a - lambda)*Math.pow( (1.+ p)/(1 + p*y) , a + b ) )){
52
return (p*y)/(1+ p*y)
53
}
54
}
55
}
56
57
function rbeta_array( arm_counts){
58
// to be used with ARMS with uniform prior.
59
samples = []
60
for (var i=0; i < arm_counts.length/2; i++){
61
samples.push(
62
rbeta(arm_counts[2*i + 1]+1, 1+arm_counts[2*i] - arm_counts[2*i+1] )
63
)
64
}
65
return samples
66
}
67
68
function draw_arm( p ){
69
if ( Math.random() < p){ return 1 } else { return 0 }
70
}
71
72
73
function update_arm( arm_number ){
74
var result = draw_arm(_PROBS[arm_number] );
75
ARMS[2*arm_number] += 1;
76
ARMS[2*arm_number+1] += result;
77
redraw(arm_number);
78
return
79
}
80
81
82
function bayesian_bandits(){
83
//for (var i = 0; i < n_pulls; i++ ){
84
//sample from Beta distributions
85
var samples = rbeta_array(ARMS);
86
var select = samples.indexOf( d3.max( samples) );
87
update_arm( select );
88
if (BB_RUN < 300){
89
BB_RUN += 1;
90
window.setTimeout( bayesian_bandits, 100 )
91
}
92
else{
93
return
94
}
95
//}
96
}
97
98
var x_array = [];
99
var _N = 100;
100
var max_data = 10
101
for ( var i =0; i < _N; i++ ){
102
x_array.push( .01*i )
103
}
104
105
var colors = ["#348ABD", "#A60628", "#7A68A6"];
106
var fill_colors = [ "rgba(52, 128, 189,0.1)", "rgba(166, 6, 40, 0.1 )", "rgba( 122, 104, 166,0.1 )"];
107
108
var w = 600,
109
h = 150,
110
margin = 15,
111
y = d3.scale.linear().domain([0, max_data]).range([h - margin,0 + margin ]),
112
x = d3.scale.linear().domain([0,_N]).range([0 + margin, w - margin])
113
114
var vis = d3.select("#beta-graphs")
115
.append("svg:svg")
116
.attr("width", w )
117
.attr("height", h )
118
119
var g = vis.append("svg:g")
120
121
var line = d3.svg.line()
122
.x(function(d, i) { return x(i); })
123
.y(y)
124
125
126
for ( var i =0; i < 3; i++){
127
var _data = pdfbeta(x_array, 1 + ARMS[2*i+1],1+ARMS[2*i] - ARMS[2*i+1] );
128
g.selectAll('path.line')
129
.data( [_data] )
130
.enter()
131
.append("svg:path")
132
.attr("stroke", colors[i] )
133
//.attr("fill", fill_colors[i] )
134
//.attr("fill", fill_colors[i] )
135
//.attr("stroke-width", 0 )
136
.attr("d", line )
137
.attr("id", "line-" + i );
138
}
139
140
141
g.append("svg:line")
142
.attr("x1", x(0))
143
.attr("y1", y(0))
144
.attr("x2", x(w))
145
.attr("y2", y(0))
146
147
g.append("svg:line")
148
.attr("x1", x(0))
149
.attr("y1", y(0))
150
.attr("x2", x(0))
151
.attr("y2", y(max_data))
152
153
g.selectAll(".xLabel")
154
.data( d3.range(0,1.2,.2) )
155
.enter().append("svg:text")
156
.attr("class", "xLabel")
157
.text(String)
158
.attr("x", function(d) { return x(100*d) })
159
.attr("y", h)
160
.attr("text-anchor", "middle")
161
.attr("dy", 0.0 )
162
/*
163
g.selectAll(".yLabel")
164
.data(y.ticks(4))
165
.enter().append("svg:text")
166
.attr("class", "yLabel")
167
.text(String)
168
.attr("x", 0)
169
.attr("y", function(d) { return y(d) })
170
.attr("text-anchor", "right")
171
.attr("dy", 4)
172
*/
173
g.selectAll(".xTicks")
174
.data(x.ticks(5))
175
.enter().append("svg:line")
176
.attr("class", "xTicks")
177
.attr("x1", function(d) { return x(d); })
178
.attr("y1", y(0))
179
.attr("x2", function(d) { return x(d); })
180
.attr("y2", y(-0.1))
181
182
vis.append("text")
183
.attr("x", (w / 2))
184
.attr("y", 15 )
185
.attr("text-anchor", "middle")
186
.style("font-size", "17px")
187
.text("Posterior Distributions");
188
189
/*
190
g.selectAll(".yTicks")
191
.data(y.ticks(4))
192
.enter().append("svg:line")
193
.attr("class", "yTicks")
194
.attr("y1", function(d) { return -1 * y(d); })
195
.attr("x1", x(-0.3))
196
.attr("y2", function(d) { return -1 * y(d); })
197
.attr("x2", x(0))
198
*/
199
200
201
202
203
<!-- Data for bar chart: Two time-series, alternating to form a single series. Bar Color will switch back & forth -->
204
205
var data = ARMS;
206
var labellist = ["Arm 1", "", "Arm 2", "", "Arm 3", ""];
207
208
var w_bar = 600,
209
h_bar = 170,
210
labelpad = 50,
211
x_bar = d3.scale.linear().domain([0, 100]).range([0, w_bar]),
212
y_bar = d3.scale.ordinal().domain(d3.range(data.length)).rangeBands([0, h_bar], .2);
213
214
var vis = d3.select("#paired-bar-chart")
215
.append("svg:svg")
216
.attr("width", w_bar + 40)
217
.attr("height", h_bar + 20)
218
.append("svg:g")
219
220
var bars = vis.selectAll("g.bar")
221
.data(data)
222
.enter().append("svg:g")
223
.attr("class", "bar")
224
.attr("transform", function(d, i) { return "translate(" + labelpad + "," + y_bar(i) + ")"; })
225
226
227
bars.append("svg:rect")
228
.attr("fill", function(d, i) { return (i%2)? colors[i]: fill_colors[i]; } ) //Alternate colors
229
.attr("width", function(d,i){ return x_bar(d)*0.5 })
230
.attr("height", y_bar.rangeBand());
231
232
bars.append("svg:text")
233
.attr("x", 0)
234
.attr("y", 10 + y_bar.rangeBand() / 2)
235
.attr("dx", -6)
236
.attr("dy", ".50em")
237
.attr("text-anchor", "end")
238
.text(function(d, i) { return labellist[i]; });
239
240
var counts = bars.append("svg:text")
241
.attr("x", 0)
242
.attr("y", 10 + y_bar.rangeBand() / 2)
243
.attr("dx", -6)
244
.attr("dy", "-.40em")
245
.attr("text-anchor", "end")
246
.text(function(d, i) { return ""; });
247
248
249
var rules = vis.selectAll("g.rule")
250
.data(x.ticks(10))
251
.enter().append("svg:g")
252
.attr("class", "rule")
253
.attr("transform", function(d) { return "translate(" + x_bar(d) + ", 0)"; });
254
255
256
rules.append("svg:line")
257
.attr("y1", 0)
258
.attr("y2", h_bar)
259
.attr("x1", labelpad)
260
.attr("x2", labelpad)
261
.attr("stroke", "white")
262
.attr("stroke-opacity", .3);
263
264
265
266
function redraw(arm_number){
267
268
var _data = []
269
for ( var i =0; i < 3; i++){
270
_data.push( pdfbeta(x_array, 1 + ARMS[2*i+1],1+ARMS[2*i] - ARMS[2*i+1] ) );
271
272
}
273
//update what is max.
274
max_data = d3.max( [
275
10,
276
d3.max(_data[0]),
277
d3.max(_data[1]),
278
d3.max(_data[2]) ])
279
280
y = d3.scale.linear().domain([0, max_data]).range([h - margin,0 + margin ])
281
line = d3.svg.line()
282
.x(function(d, i) { return x(i); })
283
.y(y)
284
285
for ( var i =0; i < 3; i++){
286
g.select("#line-" + i)
287
.data( [_data[i]] )
288
.attr("d", line )
289
}
290
291
292
293
294
295
296
bars.data(ARMS)
297
.enter().append("svg:g")
298
.attr("class", "bar")
299
.attr("transform", function(d, i) { return "translate(" + labelpad + "," + y(i) + ")"; });
300
301
302
bars.append("svg:rect")
303
.attr("fill", function(d, ix) {_ix = Math.floor(ix/2); return (ix%2)? fill_colors[_ix]: colors[_ix]; } ) //Alternate colors
304
.attr("width", function(d,i){ return x_bar(d)*0.5 })
305
.attr("height", y_bar.rangeBand());
306
307
308
counts
309
.attr("x", 0)
310
.attr("y", 10 + y_bar.rangeBand() / 2)
311
.attr("dx", function( d,i) { return !(i%2) ? 50 + 3.2*data[i] : 67 + 3.2*data[i] ;})
312
.attr("dy", "-.40em")
313
.attr("text-anchor", "end")
314
.text(function(d, i) { return !(i%2) ? data[i] + " pulls" : data[i] + " rewards" ;});
315
316
//update scoreboard
317
var rewards = ARMS[1] + ARMS[3] + ARMS[5];
318
var pulls = ARMS[0] + ARMS[2] + ARMS[4];
319
document.getElementById("rewards").innerHTML = rewards ;
320
document.getElementById("pulls").innerHTML = pulls ;
321
document.getElementById("ratio").innerHTML = (rewards/pulls).toFixed(3) ;
322
323
}
324
325
326
d3.select( "#reveal-div" )
327
.selectAll("p")
328
.data( _PROBS )
329
.enter()
330
.append("span")
331
.attr( "style", "margin-left:15; margin-right: 30px; margin-top:0" )
332
.text( function(d,i){ return d.toFixed(4) ; } )
333
//redraw() //to initialize
334
335