前言
k-means算法是一种基于样本间相似性度量的间接聚类方法,属于非监督学习方法。通过指定k值将数据自动迭代分成k组,实现数据分类,可对分类的数据进行进一步的研究。
算法原理
1.在数据中随机选取k个数据作为聚类中心
2.计算其他数据到k个聚类中心的距离(这个距离可以是欧氏距离或者其他距离)
3.根据到聚类中心的最小距离将数据分为k类
4.更新聚类中心的坐标(对分类好的数据求均值)
5.回到2重新进行分类,(进行多次迭代更新,使聚类中心趋于稳定,迭代次数可根据需要自由设定)
Matlab仿真图
来看看matlab仿真结果,先随机撒点
kmeans算法进行分类,k=4
数据成功分为4组,由于这里用的均匀分布的随机数,数据也均匀被分为k组。
算法实现
//Kmeans算法
//k:聚类数量
//points:坐标数据
//iteration:迭代计算次数
//返回:聚类中心
public static Point[] Kmeans(int k, Point[] points,int iteration){
if (points.length<k) return null;
//聚类中心
Point[] centre=new Point[k];
for(int i=0;i<centre.length;i++){
centre[i]=points[i];
}
while (--iteration>0){
//分组下标,每个数据对应聚类中心数组的下标
int[] index=new int[points.length];
//统计每组的数据数量
int[] count=new int[centre.length];
//分组
for (int i=0;i<points.length;i++){
//最小距离,-1代表没有初值
float min=-1;
//寻找最近的聚类中心
for (int j=0;j<centre.length;j++){
float d=(float) Math.sqrt((centre[j].x-points[i].x)*(centre[j].x-points[i].x)+
(centre[j].y-points[i].y)*(centre[j].y-points[i].y));
if(min<0||d<min){
min=d;
index[i]=j;
}
}
++count[index[i]];
}
//更新聚类中心
for(int i=0;i<centre.length;i++){
centre[i].x=0;
centre[i].y=0;
}
for (int i=0;i<index.length;i++){
centre[index[i]].x+=points[i].x;
centre[index[i]].y+=points[i].y;
}
for(int i=0;i<centre.length;i++){
if (count[i]==0) continue;
centre[i].x/=count[i];
centre[i].y/=count[i];
}
}
return centre;
}
我这里返回的是数据的聚类中心,当然返回数据分类也是可以的,简单起见就先这样。