k-means聚类JAVA实例

《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. k-means聚类算法原理


1、从D中随机取k个元素,作为k个簇的各自的中心。


2、分别计算剩下的元素到k个簇中心的相异度,将这些元素分别划归到相异度最低的簇。


3、根据聚类结果,重新计算k个簇各自的中心,计算方法是取簇中所有元素各自维度的算术平均数。


4、将D中全部元素按照新的中心重新聚类。


5、重复第4步,直到聚类结果不再变化。


6、将结果输出。

2. 举例说明


2.1 从D中随机取k个元素,作为k个簇的各自的中心。

private final static Integer K=2; //选K=2,也就是估算有两个簇。
下面选1 1,2,1两个点。
C0:1 1
C1:2 1

2.2 分别计算剩下的元素到k个簇中心的相异度,将这些元素分别划归到相异度最低的簇。

结果为:
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.3 根据2.2的聚类结果,重新计算k个簇各自的中心,计算方法是取簇中所有元素各自维度的算术平均数。

采取欧区距离公式。
C0 新的簇心为:1.0,1.5
C1 新的簇心为:5.857142857142857,5.714285714285714

2.4 将D中全部元素按照新的中心重新聚类。

第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


2.5  重复第4步,直到聚类结果不再变化。

当距离小于某个值的时候,就认为聚类已经聚类了,不需要再迭代,这里的值选0.001
private final static Double converge=0.001;

------------------------------------------------
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

3. JAVA实现

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 Vector  li=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;jconverge;times++){
			System.out.println("第"+times+"次迭代");
			//默认每一个list里的Vector第0个元素是质心
			for(int i=0;i 
  

4.运行结果:

C0:1 1
C1:2 1
第1次迭代
C0:的点为:1.0,2.0
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
------------------------------------------------
C0的簇心为:1.0,1.5
C1的簇心为:5.857142857142857,5.714285714285714
第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
作者:fz2543122681 发表于2014-5-30 12:50:12 原文链接
阅读:132 评论:0 查看评论

你可能感兴趣的:(means,聚类,java)