Skip to content

Instantly share code, notes, and snippets.

@Yuffster
Created February 19, 2017 12:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Yuffster/6d9d683040f5f860bb581600c2917688 to your computer and use it in GitHub Desktop.
Save Yuffster/6d9d683040f5f860bb581600c2917688 to your computer and use it in GitHub Desktop.
kmeans?
function kmeans(k, arr) {
var clusters = [];
var sorted = [...new Set(arr)].sort((a, b) => a - b);
var size = Math.abs(sorted.length/k);
for (var i = 0; sorted.length>0; i += size) {
if (sorted.length < size*2) size = size*2;
clusters.push(sorted.splice(0, size));
}
console.log(clusters.map((a) => JSON.stringify(a.sort((a, b) => a - b))));
var center = (a) => {
var mean = a.reduce((a, v) => a + v, 0)/a.length;
var closest = 0;
var dist = Infinity;
for (let n of a) {
let d = Math.abs(n-mean);
if (dist > d) {
closest = n;
dist = d;
}
}
return closest;
};
var maxdist = (arr) => {
var c = center(arr);
return arr.reduce((a, v) => (Math.abs(c-v) > a) ? v : a);
}
var variance = (...arrs) => {
var v = 0;
var t = 0;
for (let arr of arrs) {
var c = center(arr);
for (let n of arr) {
t++;
v += Math.abs(c-n);
}
} return v/t;
}
console.log('start', variance(...clusters), clusters.map(maxdist));
var m = Math.max(...clusters.map(maxdist));
var count = 100, maxiter = 50000;
while (count>0 && maxiter>0) {
for (let i in clusters) {
let c = clusters[i];
for (let j of [0, c.length-1]) {
let n = c[j];
let dist = Math.abs(center(c)-n);
let back = clusters[parseInt(i)-1],
next = clusters[parseInt(i)+1];
for (let r of [back, next]) {
if (!r) continue;
if (Math.abs(center(r)-n) < dist) {
r.push(...c.splice(j, 1));
}
}
}
let nvar = Math.max(...clusters.map(maxdist));
if (nvar < m) m = nvar;
else count--;
maxiter--;
}
}
console.log('end', variance(...clusters), clusters.map(maxdist));
console.log(clusters.map((a) => JSON.stringify(a.sort((a, b) => a - b))));
return clusters;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment