This example achieves locality-sensitive color clustering by mimicing the behavior of Kohonen's Self Organizing Maps (a type of a neural network, commonly referred as SOM). With few modifications to Kohonen's idea, it is being demonstrated that how SOMs achieve a map of locality-sensitive soft data clustering, which is used in tasks like unsupervised (and supervised) modeling.
Last active
June 30, 2016 03:55
-
-
Save saifuddin778/5c0536d69886d10875e115b9720754d0 to your computer and use it in GitHub Desktop.
Color Clustering - I
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> | |
<meta charset="utf-8"> | |
<style> | |
body { | |
text-align: center; | |
font-family: monospace; | |
} | |
.node { | |
opacity: 0.7; | |
} | |
.iter_container { | |
display: inline-block; | |
vertical-align: top; | |
margin-left: 19px; | |
background: mediumspringgreen; | |
padding: 8px; | |
border-radius: 3px; | |
width: 180px; | |
} | |
.item{ | |
display: inline; | |
font-size: 12px; | |
} | |
</style> | |
<body> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script> | |
<script> | |
var n = 25; | |
var m = n*n; | |
var width = 500; | |
var height = 500; | |
function rb(min, max) { | |
return Math.floor(Math.random() * (max - min + 1) + min); | |
} | |
function get_neighbors_params(node) { | |
var params = {}; | |
var proximity = 1; | |
params.min_x = +node.attr("x") - proximity * (+node.attr("width") + 1); | |
params.max_x = +node.attr("x") + proximity * (+node.attr("width") + 1); | |
params.min_y = +node.attr("y") - proximity * (+node.attr("height") + 1); | |
params.max_y = +node.attr("y") + proximity * (+node.attr("height") + 1); | |
return params; | |
} | |
function setup_som(width, height, n) { | |
var space = d3.select("body").append("svg").attr("width", width).attr("height", height).append("g"); | |
var m = n * n; | |
var x = 0; | |
var y = 0 - (height / n); | |
var nodes = d3.range(m).map(function(d, i) { | |
x = (width / n) * (d % n); | |
if (d % n == 0) { | |
y += (height / n); | |
} | |
var weight = [rb(rb(0, 800), rb(0, 800)), 1, Math.max(Math.random(), 0.2)]; | |
return { | |
x: x, | |
y: y, | |
width: width / n, | |
height: height / n, | |
weight: weight, | |
i: i, | |
fill: d3.hsl.apply(null, weight), | |
} | |
}); | |
space.selectAll() | |
.data(nodes) | |
.enter() | |
.append("rect") | |
.attr("class", "node") | |
.attr("width", function(d) { | |
return d.width | |
}) | |
.attr("height", function(d) { | |
return d.height | |
}) | |
.attr("x", function(d) { | |
return d.x | |
}) | |
.attr("y", function(d) { | |
return d.y | |
}) | |
.attr("rx", function(d) { | |
return d.width / 6 | |
}) | |
.attr("ry", function(d) { | |
return d.height / 6 | |
}) | |
.attr("fill", function(d) { | |
return d.fill | |
}); | |
} | |
function init_som(m) { | |
var iter_limit = 6000; | |
var t = 0; | |
var nodes = d3.selectAll(".node"); | |
var runner = setInterval( | |
function() { | |
var w; | |
var node_i = parseInt(rb(0, m)); | |
var node = nodes.filter(function(d) { | |
return d.i == node_i; | |
}); | |
node.each(function(g, i) { | |
w = g.weight; | |
}); | |
var params = get_neighbors_params(node); | |
nodes.filter(function(e) { | |
return e.x >= params.min_x && e.x <= params.max_x; | |
}) | |
.filter(function(e) { | |
return e.y >= params.min_y && e.y <= params.max_y; | |
}) | |
.each(function(d, i) { | |
var nw = []; | |
for (var ut = 0; ut < w.length; ut++) { | |
if (ut == 0) { | |
nw.push(d.weight[ut] + 0.1 * (w[ut] - d.weight[ut])); | |
} else if (ut == 2) { | |
nw.push(d.weight[ut] + Math.random() * (w[ut] - d.weight[ut])); | |
} | |
} | |
d.weight[0] = nw[0]; | |
d.weight[2] = nw[1]; | |
return; | |
}) | |
.style("fill", function(d) { | |
return d3.hsl.apply(null, d.weight); | |
}); | |
d3.select("#n_iters").text(t+1+"/"+iter_limit); | |
t += 1; | |
if (t == iter_limit) { | |
clearTimeout(runner); | |
} | |
}, | |
5 | |
); | |
} | |
setup_som(width, height, n); | |
init_som(m); | |
</script> | |
<div class="iter_container"> | |
<div class="item">ITERS: </div> | |
<div class="item" id="n_iters"></div> | |
</div> | |
</body> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment