k-means算法的Java实现

k-means算法的Java实现

    • 前言
    • 算法原理
    • Matlab仿真图
    • 算法实现

前言

k-means算法是一种基于样本间相似性度量的间接聚类方法,属于非监督学习方法。通过指定k值将数据自动迭代分成k组,实现数据分类,可对分类的数据进行进一步的研究。

算法原理

1.在数据中随机选取k个数据作为聚类中心
2.计算其他数据到k个聚类中心的距离(这个距离可以是欧氏距离或者其他距离)
3.根据到聚类中心的最小距离将数据分为k类
4.更新聚类中心的坐标(对分类好的数据求均值)
5.回到2重新进行分类,(进行多次迭代更新,使聚类中心趋于稳定,迭代次数可根据需要自由设定)

Matlab仿真图

来看看matlab仿真结果,先随机撒点
k-means算法的Java实现_第1张图片

kmeans算法进行分类,k=4
k-means算法的Java实现_第2张图片
数据成功分为4组,由于这里用的均匀分布的随机数,数据也均匀被分为k组。

算法实现

    //Kmeans算法
    //k:聚类数量
    //points:坐标数据
    //iteration:迭代计算次数
    //返回:聚类中心
    public static Point[] Kmeans(int k, ArrayList<Point> points,int iteration){
        if (points.size()<k) return null;

        //聚类中心
        Point[] centre=new Point[k];
        for(int i=0;i<centre.length;i++){
            //随机采点
            int index=(int)(Math.random()*points.size());
            centre[i]=new Point(points.get(index).x,points.get(index).y);
        }

        while (--iteration>0){
            //分组下标,每个数据对应聚类中心数组的下标
            int[] index=new int[points.size()];

            //统计每组的数据数量
            int[] count=new int[centre.length];

            //分组
            for (int i=0;i<points.size();i++){
                //最小距离,-1代表没有初值
                float min=-1;

                //寻找最近的聚类中心
                for (int j=0;j<centre.length;j++){
                    float d=(float) Math.sqrt((centre[j].x-points.get(i).x)*(centre[j].x-points.get(i).x)+
                            (centre[j].y-points.get(i).y)*(centre[j].y-points.get(i).y));
                    if(min<0||d<min){
                        min=d;
                        index[i]=j;
                    }
                }

                ++count[index[i]];
            }

            //更新聚类中心

            for (int i=0;i<index.length;i++){
                centre[index[i]].x+=points.get(i).x;
                centre[index[i]].y+=points.get(i).y;
            }

            for(int i=0;i<centre.length;i++){
                if (count[i]==0) continue;
                centre[i].x/=(count[i]+1);//+1防止count[i]=0
                centre[i].y/=(count[i]+1);
            }
        }

        return centre;
    }

我这里返回的是数据的聚类中心,当然返回数据分类也是可以的,可以根据需要修改。

你可能感兴趣的:(机器学习)