這里的k為聚類數(shù),其解決以1種屬性值(例如距離值)進(jìn)行的多點(diǎn)分類問題魔熏。
例如我們要實(shí)現(xiàn)對坐標(biāo)系中多個(gè)點(diǎn)進(jìn)行聚類分組舅柜。思路如下:
1,輸入條件1:坐標(biāo)系中的N個(gè)固定點(diǎn)集合(已知每個(gè)點(diǎn)的x捺僻、y坐標(biāo)值)
2,輸入條件2:坐標(biāo)系中任意k個(gè)聚類核心點(diǎn)的位置(通常會(huì)依據(jù)經(jīng)驗(yàn)定位初始的聚類核心點(diǎn)位置)
3崇裁,執(zhí)行過程1:遍歷所有固定點(diǎn)計(jì)算每個(gè)點(diǎn)與k各聚類核心點(diǎn)的距離匕坯,并將各點(diǎn)歸類到與其距離最近的核心點(diǎn)分類中(采用歐氏距離)。
4拔稳,執(zhí)行過程2:依次遍歷k個(gè)聚類葛峻,調(diào)整各聚類中核心點(diǎn)的位置到聚類中心(求聚類中所有點(diǎn)平均值的方式)
5,執(zhí)行過程3:再次執(zhí)行過程1巴比,直到聚類核心點(diǎn)的位置不再發(fā)生變化术奖。
Js算法如下:
/**
* 按給定的分組點(diǎn)生成分組
* @param points 所有點(diǎn)
* @param zonePoints 當(dāng)前分組點(diǎn)
*/
function kMeans(points, zonePoints) {
for (var i = 0; i < points.length; i++) {
var p = points[i];
var minDistance = -1, minTp = null;
for (var j = 0; j < zonePoints.length; j++) {
var tp = zonePoints[j];
var distance = Math.sqrt(Math.pow(p.x - tp.x, 2) + Math.pow(p.y - tp.y, 2));
if (minDistance === -1 || minDistance > distance) {//計(jì)算每個(gè)點(diǎn)到各區(qū)域核心點(diǎn)的最短距離
minDistance = distance;
minTp = tp;
}
}
p.tpId = minTp.id;
$("#p" + p.id).css('background-color', minTp.color);//設(shè)置點(diǎn)顏色
printLog('p[' + p.id + ']{x:' + p.x + ',y:' + p.y + '}所屬類別:' + (p.tpId === undefined ? '未設(shè)定' : p.tpId));
}
}
/**
* 計(jì)算每個(gè)分組的核心點(diǎn),并修改分組點(diǎn)坐標(biāo)
* @param points 所有點(diǎn)
* @param zonePoints 當(dāng)前分組點(diǎn)
*/
function calcCenter(points, zonePoints) {
var bestRegionCoreSize = 0;
for (var j = 0; j < zonePoints.length; j++) {
var tp = zonePoints[j];
//1轻绞,找到分組的所有點(diǎn)
var pSumX = 0, pSumY = 0, pSize = 0;
for (var i = 0; i < points.length; i++) {
var p = points[i];
if (tp.id === p.tpId) {
// tpGroup.push(p);
pSumX += p.x;
pSumY += p.y;
pSize++;
}
}
//2采记,求組核心點(diǎn)
if (pSize > 0) {
var pCenterX = pSumX / pSize;
var pCenterY = pSumY / pSize;
if (tp.x === pCenterX && tp.y === pCenterY) {
bestRegionCoreSize++;
printLog('<font color="'+tp.color+'">找到一個(gè)最佳聚類核心,坐標(biāo)是:{x:'+pCenterX+',y:'+pCenterY+'}</font>');
} else {
tp.x = pCenterX;
tp.y = pCenterY;
$("#tp" + tp.id).css({'left': pCenterX + 'px', 'top': pCenterY + 'px'});
}
}
}
if (bestRegionCoreSize === zonePoints.length) {
alert("已找到所有聚類的最佳核心點(diǎn)政勃,所有點(diǎn)的聚類已完成");
return true;
} else {
return false;
}
}
演示demo下載地址:https://gitee.com/inq/k-means.git