`
czhsuccess
  • 浏览: 41844 次
社区版块
存档分类
最新评论

java实现kmeans算法

阅读更多

kmeans算法是一种经典的聚类算法,其核心思想是:根据给定的聚类个数k,随机选择k个点作为初始的中心节点,然后按照样本中其他节点与这k个节点的距离进行分类。每分类一次就重新计算一次k个中心节点,直到所有样本中的节点所属的分类不再变化为止。

代码:

public class KmeansAlgorithm {
	private static final int T = 10; // 最大迭代次数
	private static final double THRESHOLD = 0.1; // 中心节点位置变化大小的阈值
	
	public ArrayList<ArrayList<Double>> getClusters(ArrayList<ArrayList<Double>> dataSet, int k) {
		int dataDimension = 0;
		if(null != dataSet && dataSet.size() < k) {
			System.out.println("data size is smaller than the number to be clustered");
		} else {
			dataDimension = dataSet.get(0).size();
		}
		
		// 为每条数据赋初始类别0
		for(int i = 0; i < dataSet.size(); i++) {
			dataSet.get(i).add(0d);
		}
		
		// 随机从数据集中选注k个点作为初始的k个中心节点
		ArrayList<ArrayList<Double>> centerData = new ArrayList<ArrayList<Double>>();
		for(int i = 0; i < k; i++) {
			centerData.add(dataSet.get(i));
		}
		
		for(int i = 0; i < T; i++) {
			for(int j = 0; j < dataSet.size(); j++) {
				double classify = 0; // classify取值为0到k-1代表k个类别
				double minDistance = computeDistance(dataSet.get(j), centerData.get(0));
				for(int l = 1; l < centerData.size(); l++) {
					if(computeDistance(dataSet.get(j), centerData.get(l)) < minDistance) {
						minDistance = computeDistance(dataSet.get(j), centerData.get(l));
						classify = l;
					}
					
				}
				dataSet.get(j).set(dataDimension, classify);
			}
			
			// 每次分类后计算中心节点的位置变化情况
			double variance = computeChange(dataSet, centerData, k, dataDimension);
			if(variance < THRESHOLD) {
				break;
			}
			
			// 每次分类后重新计算中心节点
			centerData = computeCenterData(dataSet, k, dataDimension);
		}
		return dataSet;
	}
	
	/**
	 * 
	* @Title: computeDistance 
	* @Description: 计算任意两个节点间的距离
	* @return double
	* @throws
	 */
	public double computeDistance(ArrayList<Double> d1, ArrayList<Double> d2) {
		double squareSum = 0;
		for(int i = 0; i < d1.size() - 1; i++) {
			squareSum += (d1.get(i) - d2.get(i)) * (d1.get(i) - d2.get(i));
		}
		return Math.sqrt(squareSum);
	}
	
	/**
	 * 
	* @Title: computeCenterData 
	* @Description: 计算中心节点
	* @return ArrayList<Double>
	* @throws
	 */
	public ArrayList<ArrayList<Double>> computeCenterData(ArrayList<ArrayList<Double>> dataSet, int k, int dataDimension) {
		ArrayList<ArrayList<Double>> res = new ArrayList<ArrayList<Double>>();
		for(int i = 0; i < k; i++) {
			int ClassNum = 0;
			ArrayList<Double> tmp = new ArrayList<Double>();
			for(int l = 0; l < dataDimension; l++) {
				tmp.add(0d);
			}
			for(int j = 0; j < dataSet.size(); j++) {
				if(dataSet.get(j).get(dataDimension) == i) {
					ClassNum++;
					for(int m = 0; m < dataDimension; m++) {
						tmp.set(m, tmp.get(m) + dataSet.get(j).get(m));
					}
				}
			}
			for(int l = 0; l < dataDimension; l++) {
				tmp.set(l, tmp.get(l) / (double)ClassNum);
			}
			res.add(tmp);
		}
		return res;
	}
	/**
	 * 
	* @Title: computeChange 
	* @Description: 计算两轮迭代中心节点位置的变化量
	* @return double
	* @throws
	 */
	public double computeChange(ArrayList<ArrayList<Double>> dataSet, ArrayList<ArrayList<Double>> centerData, int k, int dataDimension) {
		double variance = 0;
		ArrayList<ArrayList<Double>> originalCenterData = computeCenterData(dataSet, k, dataDimension);
		for(int i = 0; i < centerData.size(); i++) {
			variance += computeDistance(originalCenterData.get(i), centerData.get(i));
		}
		return variance;
	}
	
	public static void main(String[] args) {
		final int CLUSTER1_NUM = 4;
		final int CLUSTER2_NUM = 4;
		final int CLUSTER3_NUM = 4;
		
		ArrayList<ArrayList<Double>> dataSet = new ArrayList<ArrayList<Double>>();
		
		// 产生簇1
		for(int i = 0; i < CLUSTER1_NUM; i++) {
			ArrayList<Double> cluster1 = new ArrayList<Double>();
			cluster1.add(1 + Math.random() * 2);
			cluster1.add(1 + Math.random() * 2);
			dataSet.add(cluster1);
		}
		
		// 产生簇2
		for(int i = 0; i < CLUSTER2_NUM; i++) {
			ArrayList<Double> cluster2 = new ArrayList<Double>();
			cluster2.add(Math.random());
			cluster2.add(Math.random());
			dataSet.add(cluster2);
		}
		
		// 产生簇3
		for(int i = 0; i < CLUSTER3_NUM; i++) {
			ArrayList<Double> cluster3 = new ArrayList<Double>();
			cluster3.add(3 + Math.random());
			cluster3.add(3 + Math.random());
			dataSet.add(cluster3);
		}
		
		KmeansAlgorithm d = new KmeansAlgorithm();
		ArrayList<ArrayList<Double>> dd  = d.getClusters(dataSet, 3);
		System.out.println(dd);
	}
	
}

 

分享到:
评论

相关推荐

    kmeans算法代码实现(java)

    在Java中实现KMeans算法,你需要考虑以下几个关键点: 1. **数据结构**:首先,你需要定义一个表示样本点的数据结构,通常包含样本的特征向量。同时,还需要一个数据结构来存储每个类别的信息,包括类别编号、质心...

    java实现KMeans算法代码

    使用纯java实现KMeans模拟算法代码,随即撒点,计算K个聚类,使用了javaFX绘图工具包,结果有散点图的显示

    KMeans算法java代码

    KMeans算法是机器学习的经典算法,该文档实现了KMeans算法,文档中的数据是为了实现算法随机构造的。

    用MapReduce实现KMeans算法

    以下将详细阐述如何用MapReduce实现KMeans算法以及涉及的关键步骤。 1. **数据预处理**: 在HDFS(Hadoop Distributed File System)上存储数据是MapReduce的基础。首先,需要将原始数据转化为适合KMeans处理的...

    Kmeans_kmeans算法_

    在Java编程环境下实现KMeans算法,我们可以深入理解其实现原理和步骤,这对于数据挖掘、机器学习等领域是至关重要的。 首先,KMeans算法的基本思想是迭代寻找数据点的中心点(称为质心),并将数据点分配到最近的...

    Kmeans.rar_K._java实现Kmeans_聚类KMEANS算法

    用java语言实现的kmeans算法,将n个点分成k个聚类。

    kmeans聚类算法的java实现

    在Java中实现KMeans算法,我们可以利用编程语言的强大功能来处理大规模数据集,并将其应用于实际问题,如本例中的数据库字段分组。 1. **KMeans算法基本原理**: KMeans算法主要包含以下步骤: - 初始化:选择K个...

    kmeans算法文本聚类java源码(分词,TF/IDF等)

    《基于Java的KMeans算法实现文本聚类及TF-IDF权重计算详解》 在数据挖掘领域,文本聚类是一种常用的技术,它通过无监督学习方法将大量文本数据自动分类为不同的组,使得相同主题的文本聚集在一起。在这个过程中,...

    kmeans算法java源码工程简单实例,解压即可运行

    这个Java源码工程提供了一个简单的KMeans算法实现,方便开发者理解和运用。以下是关于KMeans算法及其Java实现的详细解释。 KMeans算法概述: KMeans算法是一种迭代的、基于距离的聚类算法。它的目标是将n个数据点...

    java实现k-means算法

    Java 实现 K-Means 算法是一个在数据挖掘领域常见的任务,它主要用于聚类分析,即将数据分组成不同的类别或簇。K-Means 是一种迭代算法,旨在...在这个过程中,了解数据库操作、算法实现以及数据处理技术是非常关键的。

    java版kmeans算法

    Java版的KMeans算法是一种基于聚类的数据分析技术,它被广泛应用于机器学习和数据分析领域。KMeans的主要目的是将数据集中的对象分配到预先设定的K个类别中,使得每个对象都属于与其最近的类别中心。这个过程通过...

    java kmeans聚合算法

    在本例中,描述提到了从Pascal语言转换到Java实现,这意味着我们将讨论如何在Java环境下构建KMeans算法来处理坐标数据,如找出一千个坐标的重心点。 KMeans算法的基本步骤如下: 1. **初始化**:选择K个初始质心...

    K_means推荐算法的java实现

    在Java中实现KMeans算法,通常需要关注以下几个核心步骤和关键组件: 1. **初始化簇中心**:随机选择一部分数据点作为初始的簇中心。这通常是算法的第一步,因为簇中心的选择会影响最终的聚类结果。 2. **数据分配...

    基于JAVA的kmeans算法

    基于JAVA的kmeans算法,随机取数,循环取平均与计算,最终分类

    java实现的KMeans聚类算法

    在实际应用中,Java实现的KMeans算法可能会遇到各种挑战,如数据预处理、维数灾难、局部最优解等问题。为了解决这些问题,可以采用不同的变种或结合其他聚类算法,如DBSCAN、谱聚类等。同时,理解KMeans的局限性也很...

    java实现聚类算法,Kmeans

    K-means聚类算法是一种迭代求解的聚类分析算法,其步骤是随机选取K个对象作为初始的聚类中心,然后计算每个对象与各个种子聚类中心之间的距离,把每个对象分配给距离它最近的聚类中心。聚类中心以及分配给它们的对象...

Global site tag (gtag.js) - Google Analytics