那么接下来就是按照上述算法进行实现啦
因为是编程小白,肯定有代码重复、变量名乱七八糟的缺点,希望大家能多多指导,不懂得相互交流~~~~
源代码:
import java.awt.List;
import java.util.ArrayList;
import java.util.Random;
/*
首先 就是KMeans算法类,在这里写成了通用类的形式
输入参数:k(最终聚类的数目),sourceData[][](输入的样本数据,其一维长度len_1代表样本数据的数量,二维长度len_2代表每个样本数据所包含的数据个数)
MAX_Its(迭代次数,迭代次数越多应该说明分类越精确吧?)。
输出参数:label[] ,其长度和sourceData相同,存储了每个样本数据的类标记,如label[2]=0,表示第三个样本数据被分配到第1类。
*/
public class KMeans {
//由于这三个数据总是共用不变的因此在这里声明
static int k=0;
static int len_1=0; //源数据数组的长度,即样本数目
static int len_2=0; //源数组二维长度,及每个样本包含数据的数目
double[][] center=new double[k][len_2];//各簇初始中心
public int[] KMeans(int k,double[][] sourceData,int MAX_Its){
KMeans.k=k;
KMeans.len_1= sourceData.length; //源数据数组的长度 也就是多少个像素点
KMeans.len_2=sourceData[0].length; //每个数据的维度 三个像素值 3
int[] label=new int[len_1]; //最终输出,存储了每个样本数据的类标记
center=initcenter(k,sourceData);
for(int i=0;i
label=classify(sourceData,center,k); //分类
center=changecenter(sourceData,label,center,k); //改变中心值
}
for(int i =0;i
return label;
}
//初始化中心值
static public double[][] initcenter(int k,double[][] sourceData){
int[] eachlabel_num=new int[k];
double[][] center=new double[k][];//各簇初始中心
Random random=new Random(System.currentTimeMillis());//生成随机数
//初始化中心值
for(int i=0;i
System.out.println(i+" random is : "+ran);
center[i]=sourceData[ran];
}
int[] label=classify(sourceData,center,k);
for (int i=0;i
eachlabel_num[j]++;
} else continue;
}
}
int repeat=0;
for(int j=0;j
if(eachlabel_num[j]==0){
initcenter(k,sourceData);
repeat++;
System.out.println("初始化中心第 "+repeat+" 次");
break;
}else continue;
}
return center;
}
//把每个数据样本分配到距离最小的中心簇
static public int[] classify(double[][] sourceData,double[][] center,int k){
int[] label=new int[len_1];
for(int i=0;i
for(int j=0;j
if(dist
label[i]=j;// 记录每个元素所在分组
}
}
}
return label;
}
//重新计算簇中心
static public double[][] changecenter(double[][] sourceData,int[] label,double[][] center,int k){
int[] eachlabel_num=new int[k];
for (int i=0;i
eachlabel_num[j]++;
} else continue;
}
}
int[][] sum=new int[k][len_2];
for(int i=0;i
}
}
for(int i=0;i
}
}
return center;
}
//计算欧式距离
static public double calEuraDist(double[] vector,double[] center,int len){
double sum=0;
for(int i=0;i
}
sum=Math.sqrt(sum);
return sum;
}
}