实验描述:
对指定数据集进行聚类分析,选择适当的聚类算法,编写程序实现,提交程序和结果报告。
数据集: Iris Data Set(见附件一) ,根据花的属性进行聚类。
数据包括四个属性:sepal length花萼长度,sepal width花萼宽度,petal length花瓣长度,petal width花瓣宽度。其中第五个值表示该样本属于哪一个类。
样本点间的距离直接用向量的欧氏距离。
实验环境和编程语言:
本实验使用的编程语言为:Java
编程环境为:Intellij idea
实现聚类的算法为:K_means算法
测试用例的样本个数为:150个
样本示例:4.9,3.0,1.4,0.2,Iris-setosa
算法分析:
这里只是简单的介绍一下k-means算法的基本思想,具体详细的设计和数学公式读者可以自行百度,这个资料很多。
可以参考这个博客http://blog.csdn.net/qll125596718/article/details/8243404/
K-means算法的基本思想是:以空间中k个点为中心进行聚类,对最靠近他们的对象归类。通过迭代的方法,逐次更新各聚类中心的值,直至得到最好的聚类结果。
假设要把样本集分为c个类别,算法描述如下:
(1)适当选择c个类的初始中心;
(2)在第k次迭代中,对任意一个样本,求其到c个中心的距离,将该样本归到距离最短的中心所在的类;
(3)利用均值等方法更新该类的中心值;
(4)对于所有的c个聚类中心,如果利用(2)(3)的迭代法更新后,值保持不变,则迭代结束,否则继续迭代。
工程和测试数据下载地址:
http://download.csdn.net/detail/qq_24369113/9711642
编程实现:
函数设计与分析:
1. public static boolean loadData(String url)
//加载测试的数据文件
2. public static void pretreatment(Vector<String> indata)
//数据预处理,将原始数据中的每一个属性值提取出来存放到Vector<double[]> data中
3. public static Vector<double[]> set_kernal(Vector<double[]> data, int a, int b, int c)
//设置初始的聚类核心,a,b,c分别表示一个类的核心在data中的编号
4. public static int choose(double[] data, double[] a, double[] b, double[] c)
//判断一个样本属于哪一个类,返回值1表示第一类,2表示第二类,3表示第三类
5. public static Vector <double[]> onestep (Vector<double[]>data,Vector<double[]> kernal)
//函数执行一次表示kmeans的一次迭代
6. public static void k_means()
//k_means算法的实现
7. public static void show_category()
//打印出所有的样本的属性和所属类别
程序源码:
源码实现:
package com.company;
import java.io.File;
import java.util.Scanner;
import java.util.Vector;
import static com.sun.org.apache.xalan.internal.lib.ExsltStrings.split;
public class Main {
public static Vector<String> indata = new Vector<>(); //存储从文件中读取的原始数据
public static Vector<double[]> data = new Vector<>(); //存储经过处理后的每一个样本的各个属性值和所属分类
public static Vector<double[]> init_kernal = new Vector<>();//存储每次迭代产生的聚类核心的每个属性值的均值
public static boolean loadData(String url) {//加载测试的数据文件
try {
Scanner in = new Scanner(new File(url));//读入文件
while (in.hasNextLine()) {
String str = in.nextLine();//将文件的每一行存到str的临时变量中
indata.add(str);//将每一个样本点的数据追加到Vector 中
}
return true;
} catch (Exception e) { //如果出错返回false
return false;
}
}
public static void pretreatment(Vector<String> indata) { //数据预处理,将原始数据中的每一个属性值