K-中心点聚类算法

(1)任意选择k个对象作为初始的簇中心点
(2)指派每个剩余对象给离他最近的中心点所表示的簇
(3)选择一个未被选择的中心点直到所有的中心点都被选择过
(4)选择一个未被选择过的非中心点对象,计算用代替的总代价并记录在S中
,直到所有非中心点都被选择过。
(5)如果在S中的所有非中心点代替所有中心点后的计算出总代价有小于0的存在,然后找出S中的用非中心点替代中心点后代价最小的一个,并用该非中心点替代对应的中心点,形成一个新的k个中心点的集合
(6)重复步骤2-5,直到没有再发生簇的重新分配,即所有的S都大于0.

代码

public class Cluster {private int id;// 标识private Point center;// 中心private List<Point> members = new ArrayList<Point>();// 成员public Cluster(int id, Point center) {this.id = id;this.center = center;}public Cluster(int id, Point center, List<Point> members) {this.id = id;this.center = center;this.members = members;}public void addPoint(Point newPoint) {if (!members.contains(newPoint)){members.add(newPoint);}else{System.out.println("样本数据点 {"+newPoint.toString()+"} 已经存在!");}}public float getdis() {float cur=0;for (Point point : members) {cur+=point.getDist()*point.getDist();}return cur;}public int getId() {return id;}public Point getCenter() {return center;}public void setCenter(Point center) {this.center = center;}public List<Point> getMembers() {return members;}@Overridepublic String toString() {String toString = "-----------Cluster"+this.getId()+"---------\n";toString+="Mid_Point:  "+center+"  Points_num:  "+members.size();for (Point point : members) {toString+="\n"+point.toString();}return toString+"\n";}
}

public class datahandler {public static List<float[]> readTxt(String fileName){List<float[]> list=new ArrayList<>();try {File filename = new File(fileName); // 读取input.txt文件InputStreamReader reader = new InputStreamReader(new FileInputStream(filename)); // 建立一个输入流对象readerBufferedReader br = new BufferedReader(reader);String line = "";line = br.readLine();while (true) {line = br.readLine();if(line==null) break;String[] temp=line.split(",");float[] c=new float[temp.length];for(int i=0;i<temp.length;i++){c[i]=Float.parseFloat(temp[i]);}list.add(c);}} catch (Exception e) {e.printStackTrace();}return list;}public static void writeTxt(String content){try { // 防止文件建立或读取失败,用catch捕捉错误并打印,也可以throw/* 读入TXT文件 */File writename = new File("src/k/output.txt"); // 相对路径,如果没有则要建立一个新的output。txt文件writename.createNewFile(); // 创建新文件BufferedWriter out = new BufferedWriter(new FileWriter(writename));out.write(content); // \r\n即为换行out.flush(); // 把缓存区内容压入文件out.close(); // 最后记得关闭文件} catch (Exception e) {e.printStackTrace();}}public static void main(String[] args) {/*        List<float[]> ret = readTxt("src/k/t2.txt");long s=System.currentTimeMillis();KMeansRun kRun = new KMeansRun(5, ret);Set<Cluster> clusterSet = kRun.run();System.out.println("K-means聚类算法运行时间:"+(System.currentTimeMillis()-s)+"ms");System.out.println("单次迭代运行次数:" + kRun.getIterTimes());StringBuilder stringBuilder=new StringBuilder();for (Cluster cluster : clusterSet) {System.out.println("Mid_Point:  "+cluster.getCenter()+" clusterId: "+cluster.getId()+"  Points_num:  "+cluster.getMembers().size());stringBuilder.append(cluster).append("\n");}writeTxt(stringBuilder.toString());*/List<float[]> ret = readTxt("src/k/t2.txt");XYSeries series = new XYSeries("xySeries");for (int x = 1; x < 20; x++) {KMeansRun kRun = new KMeansRun(x, ret);Set<Cluster> clusterSet = kRun.run();float y = 0;for (Cluster cluster : clusterSet){y+=cluster.getdis();}series.add(x, y);}XYSeriesCollection dataset = new XYSeriesCollection();dataset.addSeries(series);JFreeChart chart = ChartFactory.createXYLineChart("sum of the squared errors", // chart title"K", // x axis label"SSE", // y axis labeldataset, // dataPlotOrientation.VERTICAL,false, // include legendfalse, // tooltipsfalse // urls);ChartFrame frame = new ChartFrame("my picture", chart);frame.pack();frame.setVisible(true);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);}
}
public class DistanceCompute {/*** 求欧式距离*/public double getEuclideanDis(Point p1, Point p2) {double count_dis = 0;float[] p1_local_array = p1.getlocalArray();float[] p2_local_array = p2.getlocalArray();if (p1_local_array.length != p2_local_array.length) {throw new IllegalArgumentException("length of array must be equal!");}for (int i = 0; i < p1_local_array.length; i++) {count_dis += Math.pow(p1_local_array[i] - p2_local_array[i], 2);}return Math.sqrt(count_dis);}
}

import java.util.*;public class KMeansRun {private int kNum;                             //簇的个数private int iterNum = 200;                     //迭代次数private int iterMaxTimes = 100000;            //单次迭代最大运行次数private int iterRunTimes = 0;                 //单次迭代实际运行次数private float disDiff = (float) 0.01;         //单次迭代终止条件,两次运行中类中心的距离差private List<float[]> original_data =null;    //用于存放,原始数据集private static List<Point> pointList = null;  //用于存放,原始数据集所构建的点集private DistanceCompute disC = new DistanceCompute();private int len = 0;                          //用于记录每个数据点的维度public KMeansRun(int k, List<float[]> original_data) {this.kNum = k;this.original_data = original_data;this.len = original_data.get(0).length;//检查规范check();//初始化点集。init();}/*** 检查规范*/private void check() {if (kNum == 0){throw new IllegalArgumentException("k must be the number > 0");}if (original_data == null){throw new IllegalArgumentException("program can't get real data");}}/*** 初始化数据集,把数组转化为Point类型。*/private void init() {pointList = new ArrayList<Point>();for (int i = 0, j = original_data.size(); i < j; i++){pointList.add(new Point(i, original_data.get(i)));}}/*** 随机选取中心点,构建成中心类。*/private Set<Cluster> chooseCenterCluster() {Set<Cluster> clusterSet = new HashSet<Cluster>();Random random = new Random();for (int id = 0; id < kNum; ) {Point point = pointList.get(random.nextInt(pointList.size()));// 用于标记是否已经选择过该数据。boolean flag =true;for (Cluster cluster : clusterSet) {if (cluster.getCenter().equals(point)) {flag = false;}}// 如果随机选取的点没有被选中过,则生成一个clusterif (flag) {Cluster cluster =new Cluster(id, point);clusterSet.add(cluster);id++;}}return clusterSet;}/*** 为每个点分配一个类!*/public void cluster(Set<Cluster> clusterSet){// 计算每个点到K个中心的距离,并且为每个点标记类别号for (Point point : pointList) {float min_dis = Integer.MAX_VALUE;for (Cluster cluster : clusterSet) {float tmp_dis = (float) Math.min(disC.getEuclideanDis(point, cluster.getCenter()), min_dis);if (tmp_dis != min_dis) {min_dis = tmp_dis;point.setClusterId(cluster.getId());point.setDist(min_dis);}}}// 新清除原来所有的类中成员。把所有的点,分别加入每个类别for (Cluster cluster : clusterSet) {cluster.getMembers().clear();for (Point point : pointList) {if (point.getClusterid()==cluster.getId()) {cluster.addPoint(point);}}}}/*** 计算每个类的中心位置!*/public boolean calculateCenter(Set<Cluster> clusterSet) {boolean ifNeedIter = false;for (Cluster cluster : clusterSet) {List<Point> point_list = cluster.getMembers();float[] sumAll =new float[len];// 所有点,对应各个维度进行求和for (int i = 0; i < len; i++) {for (int j = 0; j < point_list.size(); j++) {sumAll[i] += point_list.get(j).getlocalArray()[i];}}// 计算平均值for (int i = 0; i < sumAll.length; i++) {sumAll[i] = (float) sumAll[i]/point_list.size();}// 计算两个新、旧中心的距离,如果任意一个类中心移动的距离大于dis_diff则继续迭代。if(disC.getEuclideanDis(cluster.getCenter(), new Point(sumAll)) > disDiff){ifNeedIter = true;}// 设置新的类中心位置cluster.setCenter(new Point(sumAll));}return ifNeedIter;}/*** 运行 k-means*/public Set<Cluster> run() {Set<Cluster> clusterSet= chooseCenterCluster();boolean ifNeedIter = true;while (ifNeedIter) {cluster(clusterSet);ifNeedIter = calculateCenter(clusterSet);iterRunTimes ++ ;}return clusterSet;}/*** 返回实际运行次数*/public int getIterTimes() {return iterRunTimes;}}

public class Point {private float[] localArray;private int id;private int clusterId;  // 标识属于哪个类中心。private float dist;     // 标识和所属类中心的距离。public Point(int id, float[] localArray) {this.id = id;this.localArray = localArray;}public Point(float[] localArray) {this.id = -1; //表示不属于任意一个类this.localArray = localArray;}public float[] getlocalArray() {return localArray;}public int getId() {return id;}public void setClusterId(int clusterId) {this.clusterId = clusterId;}public int getClusterid() {return clusterId;}public float getDist() {return dist;}public void setDist(float dist) {this.dist = dist;}@Overridepublic String toString() {String result = "Point_id=" + id + "  [";for (int i = 0; i < localArray.length; i++) {result += localArray[i] + " ";}return result.trim()+"] clusterId: "+clusterId;}@Overridepublic boolean equals(Object obj) {if (obj == null || getClass() != obj.getClass())return false;Point point = (Point) obj;if (point.localArray.length != localArray.length)return false;for (int i = 0; i < localArray.length; i++) {if (Float.compare(point.localArray[i], localArray[i]) != 0) {return false;}}return true;}@Overridepublic int hashCode() {float x = localArray[0];float y = localArray[localArray.length - 1];long temp = x != +0.0d ? Double.doubleToLongBits(x) : 0L;int result = (int) (temp ^ (temp >>> 32));temp = y != +0.0d ? Double.doubleToLongBits(y) : 0L;result = 31 * result + (int) (temp ^ (temp >>> 32));return result;}
}

数据挖掘—K-中心点聚类算法(Java实现)相关推荐

  1. Thinking in SQL系列之五:数据挖掘K均值聚类算法与城市分级

    原创: 牛超   2017-02-21   Mail:10867910@qq.com 引言:前一篇文章开始不再介绍简单算法,而是转到数据挖掘之旅.感谢CSDN将我前一篇机器学习C4.5决策树算法的博文 ...

  2. k中心点聚类算法伪代码_聚类算法之——K-Means、Canopy、Mini Batch K-Means

    K-Means||算法 K-Means||算法是为了解决K-Means++算法缺点而产生的一种算法: 主要思路是改变每次遍历时候的取样规则,并非按照K-Means++算法每次遍历只获取一个样本,而是每 ...

  3. k-medoid(k中心点)聚类算法Python实现

    k-means算法有个很大的缺点,就是对孤立点敏感性太高,孤立点即是脱离群众的点,与众不同的点,即在显示中与其他点不是抱在一团的点. 为了体现两者的不同,我特意温习了一下知识,在构造初始点的时候,自己 ...

  4. Python金融数据挖掘 第11章 复习思考题1 (聚类)给出一个数据集data_multivar.txt,里面有200个点坐标,在平面坐标系下可以画出它的散点图,用K均值聚类算法来训练模型,分4类。

    1.题目 给出一个数据集data_multivar.txt,里面有200个点坐标,在平面坐标系下可以画出它的散点图,如图11-12所示. data_multivar.txt 图11-12 数据集 da ...

  5. python机器学习案例系列教程——k均值聚类、k中心点聚类

    全栈工程师开发手册 (作者:栾鹏) python数据挖掘系列教程 上一篇我们学习了层次聚类.层次聚类只是迭代的把最相近的两个聚类匹配起来.并没有给出能给出多少的分组.今天我们来研究一个K均值聚类.就是 ...

  6. K-Means(K均值聚类算法)

    K-Means(K均值聚类算法) 1.前言 要学习聚类算法就要知道聚类学习算法是什么,为什么要学习聚类学习聚类学习算法,有什么用途,下面就简单的做一下介绍,并且详细的说明k-means均值聚类学习算法 ...

  7. K均值聚类算法(Kmeans)讲解及源码实现

    K均值聚类算法(Kmeans)讲解及源码实现 算法核心 K均值聚类的核心目标是将给定的数据集划分成K个簇,并给出每个数据对应的簇中心点.算法的具体步骤描述如下. 数据预处理,如归一化.离群点处理等. ...

  8. k均值聚类算法(K Means)及其实战案例

    算法说明 K均值聚类算法其实就是根据距离来看属性,近朱者赤近墨者黑.其中K表示要聚类的数量,就是说样本要被划分成几个类别.而均值则是因为需要求得每个类别的中心点,比如一维样本的中心点一般就是求这些样本 ...

  9. K-means(K均值聚类算法)算法笔记

    K-means(K均值聚类算法)算法笔记 K-means 算法,是比较简单的无监督的算法,通过设定好初始的类别k,然后不断循环迭代,将给定的数据自动分为K个类别.事实上,大家都知道K-means是怎么 ...

  10. K均值聚类算法的MATLAB实现

    K均值聚类算法的MATLAB实现 1.K-均值聚类法的概述 之前在参加数学建模的过程中用到过这种聚类方法,但是当时只是简单知道了在matlab中如何调用工具箱进行聚类,并不是特别清楚它的原理.最近因为 ...

最新文章

  1. php session存入redis
  2. Log4j 2 介绍
  3. Redis操作Hash相关API
  4. 搜索引擎web spam类型及防治策略(version 0.9)
  5. springMVC带文件的表单数据无法绑定到参数中
  6. 怎么安装Scrapy框架以及安装时出现的一系列错误(win7 64位 python3 pycharm)
  7. SAP中Search help的使用
  8. Altium AD20焊盘样式、热焊盘与反焊盘与直接连接
  9. mapinfo开发资料(转)
  10. 1讲.Cisco模拟器-小凡软件的安装使用(附视频链接)
  11. windows10专业版安装详细教程
  12. php 豆瓣api_豆瓣申请API Key教程
  13. 学校选课系统服务器繁忙,大学选课没选到怎么办
  14. 非线性规划模型、0-1整数规划模型
  15. 关于若依管理系统配置多数据源的原理分析
  16. NX/UG二次开发创建曲面偏置体
  17. hibernate配置映射的问题
  18. 交通数字孪生高速公路规划设计市政道路BIM正向改扩建设计利用实景三维无人机机载LiDAR倾斜摄影车载地面三维激光扫描仪LiDAR点云数据提取自动驾驶高精地图三维矢量车道标线3d点云标注
  19. clock jitter和clock skew
  20. [Python机器学习]Nagel-Schreckenberg(交通流)模型

热门文章

  1. 从草根到百万年薪程序员的十年风雨之路,使用指南
  2. [JS 分析] 天_眼_查 字体文件
  3. strlen和sizeof的长度区别
  4. web相关基础知识1
  5. jQuery源码分析--Event模块(1)
  6. mac 下终端 操作svn命令 以及出现证书错误的处理方法
  7. knife4j是为Java MVC框架集成Swagger生成Api文档的增强解决方案
  8. kubernetes(k8s)安装部署
  9. Activiti 简易教程
  10. 洛谷P1828 香甜的黄油 Sweet Butter