function kMeansCluster(points, numCluster, randomSource = Math.random) {
    let oldCentroids = null;
    let newCentroids = sample(points, numCluster, randomSource);
    let labels = null;
    let change = Number.MAX_VALUE;
    while (change !== 0) {
        labels = labelPoints(points, newCentroids);
        oldCentroids = newCentroids;
        newCentroids = calculateCentroids(points, labels, numCluster);
        change = calculateChange(newCentroids, oldCentroids);
    }
    return {
        labels: labels,
        centroids: newCentroids
    };
}
Perform k-means clustering.

@param {Array<Array<number>>} points N-dimensional coordinates of points to be clustered.
@param {number} numCluster How many clusters to create.
@param {Function} randomSource An optional entropy source that generates uniform values in [0, 1).
@return {kMeansReturn} Labels (same length as data) and centroids (same length as numCluster).
@throws {Error} If any centroids wind up friendless (i.e., without associated points).

@example
kMeansCluster([[0.0, 0.5], [1.0, 0.5]], 2); // => {labels: [0, 1], centroids: [[0.0, 0.5], [1.0 0.5]]}