• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
导航菜单
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • windows
  • 服务器硬件
  • 服务器运维
  • 云计算
  • 虚拟化
  • IIS教程
  • Linux
  • Apache
  • Ftp
  • DNS
  • Nginx
您的位置:首页 > 服务器 >云计算 > 二分Kmeans的java实现,二分kmeansjava

二分Kmeans的java实现,二分kmeansjava

作者:网友 字体:[增加 减小] 来源:互联网

本文主要包含二分kmeans,kmeans算法java实现,java实现kmeans,kmeans java,kmeans聚类算法java等服务器相关知识,网友希望可以进行参考

二分Kmeans的java实现,二分kmeansjava


刚刚研究了Kmeans。Kmeans是一种十分简单的聚类算法。但是他十分依赖于用户最初给定的k值。它无法发现任意形状和大小的簇,最适合于发现球状簇。他的时间复杂度为O(tkn)。kmeans算法有两个核心点:计算距离的公式&判断迭代停止的条件。一般距采用欧式距离等可以随意。判断迭代停止的条件可以有:

1) 每个簇的中心点不再变化则停止迭代

2)所有簇的点与这个簇的中心点的误差平方和(SSE)的所有簇的总和不再变化

3)设定人为的迭代次数,观察实验效果。


当初始簇心选择不好的时候聚类的效果会很差。所以后来又有一个人提出了二分k均值(bisectingkmeans),其核心思路是:将初始的一个簇一分为二计算出误差平方和最大的那个簇,对他进行再一次的二分。直至切分的簇的个数为k个停止。 其实质就是不断的对选中的簇做k=2的kmeans切分。

因为聚类的误差平方和能够衡量聚类性能,该值越小表示数据点月接近于它们的质心,聚类效果就越好。所以我们就需要对误差平方和最大的簇进行再一次的划分,因为误差平方和越大,表示该簇聚类越不好,越有可能是多个簇被当成一个簇了,所以我们首先需要对这个簇进行划分。


下面是代码,kmeans的原始代码来源于http://blog.csdn.net/cyxlzzs/article/details/7416491,我稍作了一些修改。


package org.algorithm;

import java.util.ArrayList;
import java.util.List;

/**
 * 二分k均值,实际上是对一个集合做多次的k=2的kmeans划分, 每次划分后会对sse值较大的簇再进行二分。 最终使得或分出来的簇的个数为k个则停止
 * 
 * 这里利用之前别人写好的一个kmeans的java实现作为基础类。
 * 
 * @author l0979365428
 * 
 */
public class BisectingKmeans {

	private int k;// 分成多少簇
	private List<float[]> dataSet;// 当前要被二分的簇
	private List<ClusterSet> cluster; // 簇

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		// 初始化一个Kmean对象,将k置为10
		BisectingKmeans bkm = new BisectingKmeans(5);
		// 初始化试验集
		ArrayList<float[]> dataSet = new ArrayList<float[]>();

		dataSet.add(new float[] { 1, 2 });
		dataSet.add(new float[] { 3, 3 });
		dataSet.add(new float[] { 3, 4 });
		dataSet.add(new float[] { 5, 6 });
		dataSet.add(new float[] { 8, 9 });
		dataSet.add(new float[] { 4, 5 });
		dataSet.add(new float[] { 6, 4 });
		dataSet.add(new float[] { 3, 9 });
		dataSet.add(new float[] { 5, 9 });
		dataSet.add(new float[] { 4, 2 });
		dataSet.add(new float[] { 1, 9 });
		dataSet.add(new float[] { 7, 8 });
		// 设置原始数据集
		bkm.setDataSet(dataSet);
		// 执行算法
		bkm.execute();
		// 得到聚类结果
		// ArrayList<ArrayList<float[]>> cluster = bkm.getCluster();
		// 查看结果
		// for (int i = 0; i < cluster.size(); i++) {
		// bkm.printDataArray(cluster.get(i), "cluster[" + i + "]");
		// }

	}

	public BisectingKmeans(int k) {
		// 比2还小有啥要划分的意义么
		if (k < 2) {
			k = 2;
		}
		this.k = k;

	}

	/**
	 * 设置需分组的原始数据集
	 * 
	 * @param dataSet
	 */

	public void setDataSet(ArrayList<float[]> dataSet) {
		this.dataSet = dataSet;
	}

	/**
	 * 执行算法
	 */
	public void execute() {
		long startTime = System.currentTimeMillis();
		System.out.println("BisectingKmeans begins");
		BisectingKmeans();
		long endTime = System.currentTimeMillis();
		System.out.println("BisectingKmeans running time="
				+ (endTime - startTime) + "ms");
		System.out.println("BisectingKmeans ends");
		System.out.println();
	}

	/**
	 * 初始化
	 */
	private void init() {

		int dataSetLength = dataSet.size();
		if (k > dataSetLength) {
			k = dataSetLength;
		}
	}

	/**
	 * 初始化簇集合
	 * 
	 * @return 一个分为k簇的空数据的簇集合
	 */
	private ArrayList<ArrayList<float[]>> initCluster() {
		ArrayList<ArrayList<float[]>> cluster = new ArrayList<ArrayList<float[]>>();
		for (int i = 0; i < k; i++) {
			cluster.add(new ArrayList<float[]>());
		}

		return cluster;
	}

	/**
	 * Kmeans算法核心过程方法
	 */
	private void BisectingKmeans() {
		init();

		if (k < 2) {
			// 小于2 则原样输出数据集被认为是只分了一个簇
			ClusterSet cs = new ClusterSet();
			cs.setClu(dataSet);
			cluster.add(cs);
		}
		// 调用kmeans进行二分
		cluster = new ArrayList();

		while (cluster.size() < k) {
			List<ClusterSet> clu = kmeans(dataSet);

			for (ClusterSet cl : clu) {

				cluster.add(cl);

			}

			if (cluster.size() == k)
				break;
			else// 顺序计算他们的误差平方和
			{
				
				float maxerro=0f;
				int maxclustersetindex=0;
				int i=0;
				for (ClusterSet tt : cluster) {
					//计算误差平方和并得出误差平方和最大的簇
					float erroe = CommonUtil.countRule(tt.getClu(), tt
							.getCenter());
					tt.setErro(erroe);
					
					if(maxerro<erroe)
					{
						maxerro=erroe;
						maxclustersetindex=i;
					}
					i++;
				}

				dataSet=cluster.get(maxclustersetindex).getClu();
				cluster.remove(maxclustersetindex);
				
			}
		}
		int i=0;
		for(ClusterSet sc:cluster)
		{
		CommonUtil.printDataArray(sc.getClu(),"cluster"+i);
		i++;
		}
		

	}

	/**
	 * 调用kmeans得到两个簇。
	 * 
	 * @param dataSet
	 * @return
	 */
	private List<ClusterSet> kmeans(List<float[]> dataSet) {
		Kmeans k = new Kmeans(2);

		// 设置原始数据集
		k.setDataSet(dataSet);
		// 执行算法
		k.execute();
		// 得到聚类结果
		List<List<float[]>> clus = k.getCluster();

		List<ClusterSet> clusterset = new ArrayList<ClusterSet>();

		int i = 0;
		for (List<float[]> cl : clus) {
			ClusterSet cs = new ClusterSet();
			cs.setClu(cl);
			cs.setCenter(k.getCenter().get(i));
			clusterset.add(cs);
			i++;
		}

		return clusterset;
	}

	class ClusterSet {
		private float erro;
		private List<float[]> clu;
		private float[] center;

		public float getErro() {
			return erro;
		}

		public void setErro(float erro) {
			this.erro = erro;
		}

		public List<float[]> getClu() {
			return clu;
		}

		public void setClu(List<float[]> clu) {
			this.clu = clu;
		}

		public float[] getCenter() {
			return center;
		}

		public void setCenter(float[] center) {
			this.center = center;
		}

	}
}

package org.algorithm;

import java.util.List;

/**
 * 把计算距离和误差的公式抽离出来
 * @author l0979365428
 *
 */
public class CommonUtil {

	/**
	 * 计算两个点之间的距离
	 * 
	 * @param element
	 *            点1
	 * @param center
	 *            点2
	 * @return 距离
	 */
	public static  float distance(float[] element, float[] center) {
		float distance = 0.0f;
		float x = element[0] - center[0];
		float y = element[1] - center[1];
		float z = x * x + y * y;
		distance = (float) Math.sqrt(z);

		return distance;
	}
	/**
	 * 求两点误差平方的方法
	 * 
	 * @param element
	 *            点1
	 * @param center
	 *            点2
	 * @return 误差平方
	 */
	public static  float errorSquare(float[] element, float[] center) {
		float x = element[0] - center[0];
		float y = element[1] - center[1];

		float errSquare = x * x + y * y;

		return errSquare;
	}
	/**
	 * 计算误差平方和准则函数方法
	 */
	public static  float countRule( List<float[]> cluster,float[] center) {
		float jcF = 0;
	
			for (int j = 0; j < cluster.size(); j++) {
				jcF += CommonUtil.errorSquare(cluster.get(j), center);

			}
		
	return  jcF;
	}
	/**
	 * 打印数据,测试用
	 * 
	 * @param dataArray
	 *            数据集
	 * @param dataArrayName
	 *            数据集名称
	 */
	public static  void printDataArray(List<float[]> dataArray, String dataArrayName) {
		for (int i = 0; i < dataArray.size(); i++) {
			System.out.println("print:" + dataArrayName + "[" + i + "]={"
					+ dataArray.get(i)[0] + "," + dataArray.get(i)[1] + "}");
		}
		System.out.println("===================================");
	}
}

package org.algorithm;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * K均值聚类算法
 */
public class Kmeans {
	
  


 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 二分Kmeans的java实现,二分kmeansjava

相关文章

  • Strom实时计算--简述,strom实时--
  • 【Spark1.3官方翻译】Spark快速入门,spark1.3spark
  • 需要时才去度秘一下,不如苍老师主动找你服务一下,
  • Docker安装MySQL8.0的实现方法
  • Hadoop学习笔记0001——Hadoop安装配置,hadoop学习笔记0001
  • Spark调研笔记第3篇,spark调研第3篇
  • win系统下启动linux上的kafka集群及使用,linuxkafka
  • NOSQL(一)为什么选用NoSQL?,选用nosql
  • spark一些入门资料,spark入门资料
  • MapReduce实现倒排索引,mapreduce实现索引

文章分类

  • windows
  • 服务器硬件
  • 服务器运维
  • 云计算
  • 虚拟化
  • IIS教程
  • Linux
  • Apache
  • Ftp
  • DNS
  • Nginx

最近更新的内容

    • 修改 openstack 中 nova boot 创建实例只能在10个以内的限制,openstacknova
    • Linux、hive、sqoop常用脚本,hivesqoop
    • spark core源码分析15 Shuffle详解-写流程,sparkshuffle
    • hadoop单机存储均衡和坏block处理,hadoop单机block
    • HDFS命令行接口详解,hdfs命令行详解
    • 通过iscsi协议使用ceph rbd,iscsi协议cephrbd
    • CentOS6.5系统下Hadoop2.6.0完全分布式环境安装与配置信息介绍,centos6.5hadoop2.6
    • NOSQL(四)放宽一致性约束,nosql一致性
    • Hadoop之——自定义排序算法实现排序功能,hadoop排序功能
    • hadoop中NameNode、DataNode和Client三者之间协作关系及通信方式介绍,hadoopnamenode

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有