UNPKG

@thi.ng/k-means

Version:

k-means & k-medians with customizable distance functions and centroid initializations for n-D vectors

45 lines (44 loc) 1.31 kB
import { mean, vmean } from "@thi.ng/vectors/mean"; import { vmedian } from "@thi.ng/vectors/median"; const meanCut = (k, samples) => computeCutWith(vmean, samples, samples[0].length, k).map( (x) => mean([], x) ); const medianCut = (k, samples) => computeCutWith(vmedian, samples, samples[0].length, k).map( (x) => mean([], x) ); const computeCutWith = (cut, samples, dim, depth) => { if (!samples.length) return []; if (depth <= 1) return [samples]; const channels = new Array(dim); let maxRange = 0, maxRangeID = 0, i = 0, j, n = samples.length, min, max, value, range, channel; for (; i < dim; i++) { channel = channels[i] = new Array(n); min = Infinity; max = -Infinity; for (j = 0; j < n; j++) { value = channel[j] = samples[j][i]; if (value < min) min = value; if (value > max) max = value; } range = max - min; if (range > maxRange) { maxRange = range; maxRangeID = i; } } channel = channels[maxRangeID]; const split = cut(channel); const lo = []; const hi = []; for (j = 0; j < n; j++) { (channel[j] <= split ? lo : hi).push(samples[j]); } return computeCutWith(cut, lo, dim, depth >> 1).concat( computeCutWith(cut, hi, dim, depth + 1 >> 1) ); }; export { computeCutWith, meanCut, medianCut };