JSFiddle - React, Tailwind, and code Playground
by ZhongluShi
JavaScript
exports = module.exports = kmeans;
//随机取k个中心
function randomCentroids(points, k, weightFun) {
var centroids = new Array(k);
var weights = new Array(k);
var idxs = [];
for (var i = 0; i < k; i++) {
while (true) {
var idx = parseInt(Math.random() * points.length);
//下标不能重复
if (idxs.indexOf(idx) !== -1) continue;
//权值不能相等
if (weights.indexOf(weightFun(points[idx])) !== -1) continue;
break;
}
centroids[i] = points[idx];
weights[i] = weightFun(points[idx]);
idxs.push(idx);
}
return centroids;
}
//k-means++第一次选取中心
function firstCentroids(points, k, weightFun) {
var centroids = [];
var m = k;
//随机选出第一个中心
var first = points[parseInt(Math.random() * points.length)];
centroids.push(first);
m--;
//选取剩下的中心
while (m > 0) {
//每个点到最近中心的距离
var dists = points.map(function(point) {
var dists = centroids.map(function(centroid) {
return Math.abs(weightFun(centroid) - weightFun(point))
}) return Math.min.apply(null, dists);
})
//取上面的距离中最大者
var max_dist = Math.max.apply(null, dists);
var max_idx = dists.indexOf(max_dist);
centroids.push(points[max_idx]);
m--;
}
return centroids;
}
//新的k个中心
//计算每个中心的平均权值,取聚集中权值与平均权值最接近的为中心
function newCentroids(clusters, weightFun) {
return clusters.map(function(cluster) {
var sum = cluster.reduce(function(a, b) {
return a + weightFun(b);
},
0) var mean = sum / cluster.length;
var dists = cluster.map(function(point) {
return Math.abs(weightFun(point) - mean);
}) var min_dist = Math.min.apply(null, dists);
return cluster[dists.indexOf(min_dist)];
})
}
//聚类,返回k个聚集
function classify(points, centroids, weightFun) {
var clusters = centroids.map(function() {
return...