美文网首页
机器学习经典算法1:k-means 聚类算法

机器学习经典算法1:k-means 聚类算法

作者: 阿尔卡雷特 | 来源:发表于2018-03-25 16:10 被阅读0次

    这里的k为聚类数,其解决以1种属性值(例如距离值)进行的多点分类问题。
    例如我们要实现对坐标系中多个点进行聚类分组。思路如下:
    1,输入条件1:坐标系中的N个固定点集合(已知每个点的x、y坐标值)
    2,输入条件2:坐标系中任意k个聚类核心点的位置(通常会依据经验定位初始的聚类核心点位置)
    3,执行过程1:遍历所有固定点计算每个点与k各聚类核心点的距离,并将各点归类到与其距离最近的核心点分类中(采用欧氏距离)。
    4,执行过程2:依次遍历k个聚类,调整各聚类中核心点的位置到聚类中心(求聚类中所有点平均值的方式)
    5,执行过程3:再次执行过程1,直到聚类核心点的位置不再发生变化。

    Js算法如下:

            /**
             * 按给定的分组点生成分组
             * @param points 所有点
             * @param zonePoints 当前分组点
             */
            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) {//计算每个点到各区域核心点的最短距离
                            minDistance = distance;
                            minTp = tp;
                        }
                    }
                    p.tpId = minTp.id;
                    $("#p" + p.id).css('background-color', minTp.color);//设置点颜色
                    printLog('p[' + p.id + ']{x:' + p.x + ',y:' + p.y + '}所属类别:' + (p.tpId === undefined ? '未设定' : p.tpId));
                }
            }
    
            /**
             * 计算每个分组的核心点,并修改分组点坐标
             * @param points 所有点
             * @param zonePoints 当前分组点
             */
            function calcCenter(points, zonePoints) {
                var bestRegionCoreSize = 0;
                for (var j = 0; j < zonePoints.length; j++) {
                    var tp = zonePoints[j];
                    //1,找到分组的所有点
                    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,求组核心点
                    if (pSize > 0) {
                        var pCenterX = pSumX / pSize;
                        var pCenterY = pSumY / pSize;
                        if (tp.x === pCenterX && tp.y === pCenterY) {
                            bestRegionCoreSize++;
                            printLog('<font color="'+tp.color+'">找到一个最佳聚类核心,坐标是:{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("已找到所有聚类的最佳核心点,所有点的聚类已完成");
                    return true;
                } else {
                    return false;
                }
            }
    

    演示demo下载地址:https://gitee.com/inq/k-means.git

    ScreenFlow.gif

    相关文章

      网友评论

          本文标题:机器学习经典算法1:k-means 聚类算法

          本文链接:https://www.haomeiwen.com/subject/zeahcftx.html