《mahout in action》第六章。
datafile/cluster/simple_k-means.txt数据集如下:
1 1 2 1 1 2 2 2 3 3 8 8 8 9 9 8 9 9
1、从D中随机取k个元素,作为k个簇的各自的中心。
2、分别计算剩下的元素到k个簇中心的相异度,将这些元素分别划归到相异度最低的簇。
3、根据聚类结果,重新计算k个簇各自的中心,计算方法是取簇中所有元素各自维度的算术平均数。
4、将D中全部元素按照新的中心重新聚类。
5、重复第4步,直到聚类结果不再变化。
6、将结果输出。
C0 : 1 1 C0:的点为:1.0,2.0 C1: 2 1 C1:的点为:2.0,2.0 C1:的点为:3.0,3.0 C1:的点为:8.0,8.0 C1:的点为:8.0,9.0 C1:的点为:9.0,8.0 C1:的点为:9.0,9.0
第2次迭代 C0:的点为:1.0,1.0 C0:的点为:2.0,1.0 C0:的点为:1.0,2.0 C0:的点为:2.0,2.0 C0:的点为:3.0,3.0 C1:的点为:8.0,8.0 C1:的点为:8.0,9.0 C1:的点为:9.0,8.0 C1:的点为:9.0,9.0
------------------------------------------------ C0的簇心为:1.6666666666666667,1.75 C1的簇心为:7.971428571428572,7.942857142857143 各个簇心移动中最小的距离为,move=0.7120003121097943 第3次迭代 C0:的点为:1.0,1.0 C0:的点为:2.0,1.0 C0:的点为:1.0,2.0 C0:的点为:2.0,2.0 C0:的点为:3.0,3.0 C1:的点为:8.0,8.0 C1:的点为:8.0,9.0 C1:的点为:9.0,8.0 C1:的点为:9.0,9.0 ------------------------------------------------ C0的簇心为:1.777777777777778,1.7916666666666667 C1的簇心为:8.394285714285715,8.388571428571428 各个簇心移动中最小的距离为,move=0.11866671868496578 第4次迭代 C0:的点为:1.0,1.0 C0:的点为:2.0,1.0 C0:的点为:1.0,2.0 C0:的点为:2.0,2.0 C0:的点为:3.0,3.0 C1:的点为:8.0,8.0 C1:的点为:8.0,9.0 C1:的点为:9.0,8.0 C1:的点为:9.0,9.0 ------------------------------------------------ C0的簇心为:1.7962962962962965,1.7986111111111114 C1的簇心为:8.478857142857143,8.477714285714285 各个簇心移动中最小的距离为,move=0.019777786447494432 第5次迭代 C0:的点为:1.0,1.0 C0:的点为:2.0,1.0 C0:的点为:1.0,2.0 C0:的点为:2.0,2.0 C0:的点为:3.0,3.0 C1:的点为:8.0,8.0 C1:的点为:8.0,9.0 C1:的点为:9.0,8.0 C1:的点为:9.0,9.0 ------------------------------------------------ C0的簇心为:1.799382716049383,1.7997685185185184 C1的簇心为:8.495771428571429,8.495542857142857 各个簇心移动中最小的距离为,move=0.003296297741248916 第6次迭代 C0:的点为:1.0,1.0 C0:的点为:2.0,1.0 C0:的点为:1.0,2.0 C0:的点为:2.0,2.0 C0:的点为:3.0,3.0 C1:的点为:8.0,8.0 C1:的点为:8.0,9.0 C1:的点为:9.0,8.0 C1:的点为:9.0,9.0 ------------------------------------------------ C0的簇心为:1.7998971193415638,1.7999614197530864 C1的簇心为:8.499154285714287,8.499108571428572 各个簇心移动中最小的距离为,move=5.49382956874724E-4
package mysequence.machineleaning.clustering.kmeans; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; import java.util.Vector; import mysequence.machineleaning.clustering.canopy.Point; public class MyKmeans { static Vectorli=new Vector (); //static List li=new ArrayList (); static List > list=new ArrayList >(); //每次迭代保存结果,一个vector代表一个簇 private final static Integer K=2; //选K=2,也就是估算有两个簇。 private final static Double converge=0.001; //当距离小于某个值的时候,就认为聚类已经聚类了,不需要再迭代,这里的值选0.001 //读取数据 public static final void readF1() throws IOException { String filePath="datafile/cluster/simple_k-means.txt"; BufferedReader br = new BufferedReader(new InputStreamReader( new FileInputStream(filePath))); for (String line = br.readLine(); line != null; line = br.readLine()) { if(line.length()==0||"".equals(line))continue; String[] str=line.split(" "); Point p0=new Point(); p0.setX(Double.valueOf(str[0])); p0.setY(Double.valueOf(str[1])); li.add(p0); //System.out.println(line); } br.close(); } //math.sqrt(double n) //扩展下,如果要给m开n次方就用java.lang.StrictMath.pow(m,1.0/n); //采用欧氏距离 public static Double DistanceMeasure(Point p1,Point p2){ Double tmp=StrictMath.pow(p2.getX()-p1.getX(), 2)+StrictMath.pow(p2.getY()-p1.getY(), 2); return Math.sqrt(tmp); } //计算新的簇心 public static Double CalCentroid(){ System.out.println("------------------------------------------------"); Double movedist=Double.MAX_VALUE; for(int i=0;i subli=list.get(i); Point po=new Point(); Double sumX=0.0; Double sumY=0.0; Double Clusterlen=Double.valueOf(subli.size()); for(int j=0;j converge;times++){ System.out.println("第"+times+"次迭代"); //默认每一个list里的Vector第0个元素是质心 for(int i=0;i vect=new Vector (); Point p=new Point(); p=li.get(k); vect.add(p); list.add(vect); } System.out.println("第1次迭代"); //默认每一个list里的Vector第0个元素是质心 for(int i=K;i
4.运行结果: