`
GhostFromheaven
  • 浏览: 397057 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

k-均值算法的java实现

阅读更多
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class KAverage {
	private int sampleCount = 0;
	private int dimensionCount = 0;
	private int centerCount = 0;
	private double[][] sampleValues;
	private double[][] centers;
	private double[][] tmpCenters;
	private String dataFile = "";

	/**
	 * 通过构造器传人数据文件
	 */
	public KAverage(String dataFile) throws NumberInvalieException {
		this.dataFile = dataFile;
	}

	/**
	 * 第一行为s;d;c含义分别为样例的数目,每个样例特征的维数,聚类中心个数 文件格式为d[,d]...;d[,d]... 如:1,2;2,3;1,5
	 * 每一维之间用,隔开,每个样例间用;隔开。结尾没有';' 可以有多行
	 */

	private int initData(String fileName) {
		String line;
		String samplesValue[];
		String dimensionsValue[] = new String[dimensionCount];
		BufferedReader in;
		try {
			in = new BufferedReader(new FileReader(fileName));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			return -1;
		}
		/*
		 * 预处理样本,允许后面几维为0时,不写入文件
		 */
		for (int i = 0; i < sampleCount; i++) {
			for (int j = 0; j < dimensionCount; j++) {
				sampleValues[i][j] = 0;
			}
		}

		int i = 0;
		double tmpValue = 0.0;
		try {
			line = in.readLine();
			String params[] = line.split(";");
			if (params.length != 3) {// 必须为3个参数,否则错误
				return -1;
			}
			/**
			 * 获取参数
			 */
			this.sampleCount = Integer.parseInt(params[0]);
			this.dimensionCount = Integer.parseInt(params[1]);
			this.centerCount = Integer.parseInt(params[2]);
			if (sampleCount <= 0 || dimensionCount <= 0 || centerCount <= 0) {
				throw new NumberInvalieException("input number <= 0.");
			}
			if (sampleCount < centerCount) {
				throw new NumberInvalieException(
						"sample number < center number");
			}

			sampleValues = new double[sampleCount][dimensionCount + 1];
			centers = new double[centerCount][dimensionCount];
			tmpCenters = new double[centerCount][dimensionCount];

			while ((line = in.readLine()) != null) {
				samplesValue = line.split(";");
				for (int j = 0; j < samplesValue.length; j++) {
					dimensionsValue = samplesValue[j].split(",");
					for (int k = 0; k < dimensionsValue.length; k++) {
						tmpValue = Double.parseDouble(dimensionsValue[k]);
						sampleValues[i][k] = tmpValue;
					}
					i++;
				}
			}

		} catch (IOException e) {
			e.printStackTrace();
			return -2;
		} catch (Exception e) {
			e.printStackTrace();
			return -3;
		}
		return 1;
	}

	/**
	 * 返回样本中第s1个和第s2个间的欧式距离
	 */
	private double getDistance(int s1, int s2) throws NumberInvalieException {
		double distance = 0.0;
		if (s1 < 0 || s1 >= sampleCount || s2 < 0 || s2 >= sampleCount) {
			throw new NumberInvalieException("number out of bound.");
		}
		for (int i = 0; i < dimensionCount; i++) {
			distance += (sampleValues[s1][i] - sampleValues[s2][i])
					* (sampleValues[s1][i] - sampleValues[s2][i]);
		}

		return distance;
	}

	/**
	 * 返回给定两个向量间的欧式距离
	 */
	private double getDistance(double s1[], double s2[]) {
		double distance = 0.0;
		for (int i = 0; i < dimensionCount; i++) {
			distance += (s1[i] - s2[i]) * (s1[i] - s2[i]);
		}
		return distance;
	}

	/**
	 * 更新样本中第s个样本的最近中心
	 */
	private int getNearestCenter(int s) {
		int center = 0;
		double minDistance = Double.MAX_VALUE;
		double distance = 0.0;
		for (int i = 0; i < centerCount; i++) {
			distance = getDistance(sampleValues[s], centers[i]);
			if (distance < minDistance) {
				minDistance = distance;
				center = i;
			}
		}
		sampleValues[s][dimensionCount] = center;
		return center;
	}

	/**
	 * 更新所有中心
	 */
	private void updateCenters() {
		double center[] = new double[dimensionCount];
		for (int i = 0; i < dimensionCount; i++) {
			center[i] = 0;
		}
		int count = 0;
		for (int i = 0; i < centerCount; i++) {
			count = 0;
			for (int j = 0; j < sampleCount; j++) {
				if (sampleValues[j][dimensionCount] == i) {
					count++;
					for (int k = 0; k < dimensionCount; k++) {
						center[k] += sampleValues[j][k];
					}
				}
			}
			for (int j = 0; j < dimensionCount; j++) {
				centers[i][j] = center[j] / count;
			}
		}
	}

	/**
	 * 判断算法是否终止
	 */
	private boolean toBeContinued() {
		for (int i = 0; i < centerCount; i++) {
			for (int j = 0; j < dimensionCount; j++) {
				if (tmpCenters[i][j] != centers[i][j]) {
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * 关键方法,调用其他方法,处理数据
	 */
	public void doCaculate() {
		initData(dataFile);

		for (int i = 0; i < centerCount; i++) {
			for (int j = 0; j < dimensionCount; j++) {
				centers[i][j] = sampleValues[i][j];
			}
		}
		for (int i = 0; i < centerCount; i++) {
			for (int j = 0; j < dimensionCount; j++) {
				tmpCenters[i][j] = 0;
			}
		}

		while (toBeContinued()) {
			for (int i = 0; i < sampleCount; i++) {
				getNearestCenter(i);
			}
			for (int i = 0; i < centerCount; i++) {
				for (int j = 0; j < dimensionCount; j++) {
					tmpCenters[i][j] = centers[i][j];
				}
			}
			updateCenters();
			System.out
					.println("******************************************************");
			showResultData();
		}
	}

	/*
	 * 显示数据
	 */
	private void showSampleData() {
		for (int i = 0; i < sampleCount; i++) {
			for (int j = 0; j < dimensionCount; j++) {
				if (j == 0) {
					System.out.print(sampleValues[i][j]);
				} else {
					System.out.print("," + sampleValues[i][j]);
				}
			}
			System.out.println();
		}
	}

	/*
	 * 分组显示结果
	 */
	private void showResultData() {
		for (int i = 0; i < centerCount; i++) {
			System.out.println("第" + (i + 1) + "个分组内容为:");
			for (int j = 0; j < sampleCount; j++) {
				if (sampleValues[j][dimensionCount] == i) {
					for (int k = 0; k <= dimensionCount; k++) {
						if (k == 0) {
							System.out.print(sampleValues[j][k]);
						} else {
							System.out.print("," + sampleValues[j][k]);
						}
					}
					System.out.println();
				}
			}
		}
	}

	public static void main(String[] args) {
		/*
		 *也可以通过命令行得到参数
		 */
		String fileName = "D:\\eclipsejava\\K-Average\\src\\sample.txt";
		if(args.length > 0){
			fileName = args[0];
		}
		
		try {
			KAverage ka = new KAverage(fileName);
			ka.doCaculate();
			System.out
					.println("***************************<<result>>**************************");
			ka.showResultData();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}



/*
 * 根据自己的需要定义一些异常,使得系统性更强
 */
public class NumberInvalieException extends Exception {
	private String cause;
	
	public NumberInvalieException(String cause){
		if(cause == null || "".equals(cause)){
			this.cause = "unknow";
		}else{
			this.cause = cause;
		}
	}
	@Override
	public String toString() {
		return "Number Invalie!Cause by " + cause;
	}
}


测试数据
20;2;4
0,0;1,0;0,1;1,1;2,1;1,2;2,2;3,2;6,6;7,6
8,6;6,7;7,7;8,7;9,7;7,8;8,8;9,8;8,9;9,9
测试结果
***************************<<result>>**************************
第1个分组内容为:
0.0,0.0,0.0
1.0,0.0,0.0
0.0,1.0,0.0
1.0,1.0,0.0
2.0,1.0,0.0
1.0,2.0,0.0
2.0,2.0,0.0
3.0,2.0,0.0
第2个分组内容为:
6.0,6.0,1.0
7.0,6.0,1.0
8.0,6.0,1.0
6.0,7.0,1.0
7.0,7.0,1.0
8.0,7.0,1.0
9.0,7.0,1.0
7.0,8.0,1.0
8.0,8.0,1.0
9.0,8.0,1.0
8.0,9.0,1.0
9.0,9.0,1.0
分享到:
评论

相关推荐

    JAVA实现K-均值算法

    在这个名为"JAVA实现K-均值算法"的项目中,作者提供了一个用JAVA编写的K-均值聚类算法实现,支持不限维度的数据点。 首先,我们来深入理解K-均值算法的核心概念: 1. **K值选择**:K值是预先设定的聚类数量,它对...

    K-均值算法

    在实际应用中,K-均值算法可以通过各种编程语言实现,如Python的`scikit-learn`库,Java的`ELKI`,R的`cluster`包等。这些库提供了现成的接口,方便快速地进行聚类分析。 通过理解K-均值算法的工作原理,我们可以...

    K-Means算法java实现

    Java作为一种通用且广泛使用的编程语言,提供了实现K-Means算法的良好平台,尤其适合初学者学习数据挖掘技术。 K-Means算法的核心步骤包括初始化中心点、计算样本到中心点的距离、重新分配样本点所属类别以及更新...

    k-means算法Java实现

    在Java中实现k-means算法,我们需要以下几个关键步骤: 1. **初始化质心**:从数据集中随机选择k个数据点作为初始质心,可以使用`Random`类来实现。 2. **数据分配**:遍历每个数据点,计算它与所有质心的距离,将...

    K-means算法java实现

    k-means 算法接受输入量 k ;然后将n个数据对象划分为 k个聚类以便使得所获得的聚类满足:同一聚类中的对象相似度较高;而不同聚类中的对象相似度较小。... &lt;br&gt;这是个基于多线程的java实现的K-means算法程序

    k-means 算法java实现

    在Java中实现k-means算法,可以让我们在各种数据集上进行有效的数据分组,从而揭示数据的潜在结构。以下是对k-means算法及其Java实现的详细说明。 **k-means算法原理** 1. **目标**: k-means算法旨在将数据集划分...

    数据挖掘 k-means算法 java实现

    在Java环境下实现k-means算法,可以为数据分析和预测模型提供强大的支持。 k-means算法的核心思想是通过迭代过程将数据集中的样本点分配到预先设定的k个聚类中,使得同一类内的样本点彼此相似,不同类的样本点相异...

    k均值算法java源代码

    在Java编程中,实现k均值算法通常涉及到以下几个关键步骤和数据结构: 1. **数据结构**: - `Centroid` 类表示质心,包含坐标属性 `mCx` 和 `mCy` 分别代表x轴和y轴的坐标值,以及所属的`Cluster`对象。 - `...

    k-means kmeans k均值 算法 java

    此外,k-means算法在Java中的实现可以结合各种数据结构和算法,例如使用ArrayList或LinkedList存储数据点,使用HashMap或HashSet快速查找最近的质心。为了优化性能,还可以考虑多线程处理大规模数据。 总结,k-...

    K-means聚类算法JAVA程序实现

    在JAVA程序实现中,K-means算法的关键步骤包括初始化、迭代和终止条件。 首先,我们需要初始化聚类中心。通常,我们随机选择数据集中的K个点作为初始聚类中心。这里的K是用户指定的类别数量,也是我们想要找到的...

    数据挖掘中考k-means算法的java实现

    在这个场景下,我们关注的是k-means算法的Java实现。k-means是一种广泛应用的无监督学习算法,用于聚类分析,即将数据集分成多个离散的、具有相似属性的簇。 k-means算法的基本思想是通过迭代过程将数据点分配到...

    K-Means算法--Java实现

    在Java中实现K-Means算法,我们需要理解以下几个核心步骤和相关概念: 1. **初始化**:首先,我们需要选择K个初始质心(centroid),通常是随机选取数据集中的K个点作为初始中心。这些质心将成为簇的代表。 2. **...

    数据挖掘 K均值聚类算法的JAVA实现

    3. 实现K均值算法: - 初始化聚类中心:随机选择K个数据点作为初始中心。 - 循环执行分配和更新步骤,直到满足停止条件。 - 分配步骤:遍历所有数据点,计算与所有聚类中心的距离,将其分配给最近的类别。 - ...

    多维k-means聚类算法java实现,导入直接运行

    下面将详细介绍多维k-means聚类算法及其Java实现的关键点。 **一、k-means算法简介** 1. **目标与原理**:k-means的目标是将数据集中的n个样本点分配到k个聚类中,使得每个样本点与其所在聚类中心的距离平方和最小...

    java k-means可视化程序

    Java K-Means 可视化程序是一种基于Java编程语言实现的数据分析工具,主要用于执行聚类算法中的K-Means方法,并将结果以图形化的形式展示出来。K-Means是一种广泛应用的无监督学习算法,用于将数据集分成不同的簇...

    3500基于k-均值的正文抽取.zip

    标题中的“3500基于k-均值的正文抽取”指的是一个使用k-均值算法来实现的文本摘要系统,可能是一个Java编程项目。k-均值算法是一种常见的无监督学习方法,常用于数据聚类,这里被应用于正文抽取,即从文本中找出关键...

    k-means聚类算法

    在原始的K-均值算法中,存在一个关键步骤——初始化中心点,这个过程有时可能导致结果的不稳定性和不准确性。 **改进的K-均值算法** 针对原始K-均值算法的中心点初始化问题,研究者们提出了一些改进策略。一种常见...

Global site tag (gtag.js) - Google Analytics