kMeans算法JAVA实现

k-means 算法 接受参数 k ;然后将事先输入的n个数据对象划分为 k个聚类以便使得所获得的聚类满足:同一聚类中的对象相似度较高;而不同聚类中的对象相似度较小。聚类相似度是利用各聚类中对象的均值所获得一个“中心对象”(引力中心)来进行计算的。

K-means算法是最为经典的基于划分的聚类方法,是十大经典数据挖掘算法之一。K-means算法的基本思想是:以空间中k个点为中心进行聚类,对最靠近他们的对象归类。通过迭代的方法,逐次更新各聚类中心的值,直至得到最好的聚类结果。

假设要把样本集分为c个类别,算法描述如下:
(1)适当选择c个类的初始中心;
(2)在第k次迭代中,对任意一个样本,求其到c个中心的距离,将该样本归到距离最短的中心所在的类;
(3)利用均值等方法更新该类的中心值;
(4)对于所有的c个聚类中心,如果利用(2)(3)的迭代法更新后,值保持不变,则迭代结束,否则继续迭代。

该算法的最大优势在于简洁和快速。算法的关键在于初始中心的选择和距离公式。

实现步骤:
 * 1. 首先是随机获取总体中的K个元素作为总体的K个中心;
 * 2. 接下来对总体中的元素进行分类,每个元素都去判断自己到K个中心的距离,并归类到最近距离中心去;
 * 3. 计算每个聚类的平均值,并作为新的中心点
 * 4. 重复2,3步骤,直到这k个中线点不再变化(收敛了),或执行了足够多的迭代

代码实现:
package com.kMeans;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

/**
 * k-Means算法,聚类算法;
 * 实现步骤:1. 首先是随机获取总体中的K个元素作为总体的K个中心;
 * 2. 接下来对总体中的元素进行分类,每个元素都去判断自己到K个中心的距离,并归类到最近距离中心去;
 * 3. 计算每个聚类的平均值,并作为新的中心点
 * 4. 重复2,3步骤,直到这k个中线点不再变化(收敛了),或执行了足够多的迭代
 */
public class KMeans {

	private static double[][] DATA = { { 5.1, 3.5, 1.4, 0.2},
			{ 4.9, 3.0, 1.4, 0.2 },{ 4.7, 3.2, 1.3, 0.2 },
			{ 4.6, 3.1, 1.5, 0.2 },{ 5.0, 3.6, 1.4, 0.2 },
			{ 7.0, 3.2, 4.7, 1.4 },{ 6.4, 3.2, 4.5, 1.5 },
			{ 6.9, 3.1, 4.9, 1.5 },{ 5.5, 2.3, 4.0, 1.3 }, 
			{ 6.5, 2.8, 4.6, 1.5 },{ 5.7, 2.8, 4.5, 1.3 },
			{ 6.5, 3.0, 5.8, 2.2 },{ 7.6, 3.0, 6.6, 2.1 },
			{ 4.9, 2.5, 4.5, 1.7 },{ 7.3, 2.9, 6.3, 1.8 }, 
			{ 6.7, 2.5, 5.8, 1.8 },{ 6.9, 3.1, 5.1, 2.3 } };
	public int k;//k个中心点
	public int[] memberShip;
	public int[] centersIndex;
	public double[][] centers;
	public int[] elementsInCenters;
	
	
	public static void main(String[] args) {
		KMeans kmeans = new KMeans(5);
		String lastMembership = "";
		String nowMembership = "";
		int i=0;
		while(true){
			i++;
			kmeans.randomCenters();
			System.out.println("随机选中的中心index为:"+Arrays.toString(kmeans.centersIndex));
			kmeans.calMemberShip();
			nowMembership = Arrays.toString(kmeans.memberShip);
			System.out.println("DATA聚类之后Membership为:"+nowMembership);
			System.out.println("Elements in centers cnt:"+Arrays.toString(kmeans.elementsInCenters));
			if(nowMembership.equals(lastMembership)){
				System.out.println("本次聚类与上次相同,退出执行!");
				System.out.println("一共聚类了 "+i+" 次!");
				kmeans.calNewCenters();
				System.out.println("新中心点为:"+Arrays.deepToString(kmeans.centers));
				double totalDistance = kmeans.computeTotalDistance();
				System.out.println("totalDistance : "+totalDistance);
				break;
			}else{
				lastMembership = nowMembership;
			}
			System.out.println("----------------华丽的分割线----------------");
		}
	}
	
	public KMeans(int k){
		this.k = k;
	}

	//计算临近距离
	public double manhattanDistince(double []paraFirstData,double []paraSecondData){
		double tempDistince = 0;
		if((paraFirstData!=null && paraSecondData!=null) && paraFirstData.length==paraSecondData.length){
			for(int i=0;i

运行结果截图:

从上面截图可见,执行了48083次随机质心的选取,聚类,才趋于收敛(即前后两次聚类效果没变化)。

你可能感兴趣的:(数据挖掘/算法)