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

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;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/392079.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用akka构建高并发程序_如何使用Akka Cluster创建简单的应用程序

使用akka构建高并发程序If you read my previous story about Scalachain, you probably noticed that it is far from being a distributed system. It lacks all the features to properly work with other nodes. Add to it that a blockchain composed by a single node is…

pandas之数值计算与统计

数值计算与统计 对于DataFrame来说&#xff0c;求和、最大、最小、平均等统计方法&#xff0c;默认是按列进行统计&#xff0c;即axis 0&#xff0c;如果添加参数axis 1则会按照行进行统计。 如果存在空值&#xff0c;在统计时默认会忽略空值&#xff0c;如果添加参数skipna …

python自动化数据报告_如何:使用Python将实时数据自动化到您的网站

python自动化数据报告This tutorial will be helpful for people who have a website that hosts live data on a cloud service but are unsure how to completely automate the updating of the live data so the website becomes hassle free. For example: I host a websit…

一颗站在技术边缘的土豆

2012年开始上专业课&#xff0c;2013年打了一年游戏&#xff0c;年底专业课忘光了&#xff0c;但是蒙混过关没挂科&#xff0c;2014年7月份毕业&#xff0c;对这个社会充满向往。2014年9月份——方正代理商做网络安全公司。2015年3月份跳槽到一家vmware代理商公司。2016年6月&a…

leetcode 839. 相似字符串组(并查集)

如果交换字符串 X 中的两个不同位置的字母&#xff0c;使得它和字符串 Y 相等&#xff0c;那么称 X 和 Y 两个字符串相似。如果这两个字符串本身是相等的&#xff0c;那它们也是相似的。 例如&#xff0c;“tars” 和 “rats” 是相似的 (交换 0 与 2 的位置)&#xff1b; “r…

android intent参数是上次的结果,【Android】7.0 Intent向下一个活动传递数据、返回数据给上一个活动...

1.0 可以利用Intent吧数据传递给上一个活动&#xff0c;新建一个叫“hellotest01”的项目。新建活动FirstActivity&#xff0c;勾选“Generate Layout File”和“Launcher Activity”。image修改AndroidMainifest.xml中的内容&#xff1a;android:name".FirstActivity&quo…

实习一年算工作一年吗?_经过一年的努力,我如何找到软件工程工作

实习一年算工作一年吗?by Andrew Ngo通过安德鲁恩戈 经过一年的努力&#xff0c;我如何找到软件工程工作 (How I landed a software engineering job after a year of hard work) Many of us think the path to becoming a software engineer requires years of education an…

学习深度学习需要哪些知识_您想了解的有关深度学习的所有知识

学习深度学习需要哪些知识有关深层学习的FAU讲义 (FAU LECTURE NOTES ON DEEP LEARNING) Corona was a huge challenge for many of us and affected our lives in a variety of ways. I have been teaching a class on Deep Learning at Friedrich-Alexander-University Erlan…

参加开发竞赛遇到的问题【总结】

等比赛完就写。 转载于:https://www.cnblogs.com/jiangyuanjia/p/11261978.html

html5--3.16 button元素

html5--3.16 button元素 学习要点 掌握button元素的使用button元素 用来建立一个按钮从功能上来说&#xff0c;与input元素建立的按钮相同button元素是双标签&#xff0c;其内部可以配置图片与文字&#xff0c;进行更复杂的样式设计不仅可以在表单中使用&#xff0c;还可以在其…

如何注册鸿蒙id,鸿蒙系统真机调试证书 和 设备ID获取

鸿蒙系统真机调试创建项目创建项目创建应用创建鸿蒙应用(注意&#xff0c;测试阶段需要发邮件申请即可)关联应用项目进入关联 添加引用准备调试使用的 p12 和证书请求 csr使用以下命令// 别名"test"可以修改&#xff0c;但必须前后一致&#xff0c;密码请自行修改key…

Java—实现 IOC 功能的简单 Spring 框架

编写一个实现 IOC 功能的简单 Spring 框架&#xff0c;包含对象注册、对象管理、及暴 露给外部获取对象的功能&#xff0c;并编写测试程序。扩展注册器的方式&#xff0c;要求采用 XML 和 txt 文件。 源代码 package myspring;import java.lang.reflect.Method; import java.…

读zepto核心源码学习JS笔记(3)--zepto.init()

上篇已经讲解了zepto.init()的几种情况,这篇就继续记录这几种情况下的具体分析. 1. 首先是第一种情况,selector为空 既然是反向分析,那我们先看看这句话的代码; if (!selector) return zepto.Z() 这里的返回值为zepto.Z();那我们继续往上找zepto.Z()函数 zepto.Z function(dom…

css flexbox模型_Flexbox和CSS Grid之间的主要区别

css flexbox模型by Shaira Williams由莎拉威廉姆斯(Shaira Williams) Flexbox和CSS Grid之间的主要区别 (The main differences between Flexbox and CSS Grid) Dimensions define the primary demarcation between Flexbox and CSS Grid. Flexbox was designed specifically …

置信区间估计 预测区间估计_估计,预测和预测

置信区间估计 预测区间估计Estimation implies finding the optimal parameter using historical data whereas prediction uses the data to compute the random value of the unseen data.估计意味着使用历史数据找到最佳参数&#xff0c;而预测则使用该数据来计算未见数据的…

鸿蒙系统还会推出吗,华为明年所有自研设备都升级鸿蒙系统,还会推出基于鸿蒙系统的新机...

不负期许&#xff0c;华为鸿蒙OS手机版如期而至。今日(12月15日)&#xff0c;鸿蒙OS 2.0手机开发者Beta版本正式上线&#xff0c;支持运行安卓应用&#xff0c;P40、Mate 30系列可申请公测。国内媒体报道称&#xff0c;华为消费者业务软件部副总裁杨海松表示&#xff0c;按照目…

C#中将DLL文件打包到EXE文件

1&#xff1a;在工程目录增加dll目录&#xff0c;然后将dll文件复制到此目录&#xff0c;例如&#xff1a; 2&#xff1a;增加引用&#xff0c;定位到工程的dll目录&#xff0c;选中要增加的dll文件 3&#xff1a;修改dll文件夹下面的dll文件属性 选中嵌入式资源&#xff0c;不…

PopupMenu控件的使用

1、用PopupMenu控件能进行右键菜单的实现&#xff0c;它的实现还需要绑定到barManager控件上&#xff0c;在barManager的Customize中添加右键所需要显示的功能。 2、PopupMenu属性栏中绑定Manager为barManager&#xff1b; 3、窗体加载事件中创建 this.popupMenu1.AddItems(new…

Java—动态代理

动态代理利用了JDK API&#xff0c;动态地在内存中构建代理对象&#xff0c;从而实现对目标对象的代理功能。动态代理又被称为JDK代理或接口代理。 静态代理与动态代理的区别主要在&#xff1a; 静态代理在编译时就已经实现&#xff0c;编译完成后代理类是一个实际的class文件…

Oracle VM Virtual Box的安装

安装Oracle VM Virtual Box安装扩展插件 选择"管理""全局设定" 在设置对话框中&#xff0c;选择"扩展" 选择"添加包" 找到"Oracle_VM_VirtualBox_Extension_Pack-4.1.18-78361"&#xff0c;点击"打开" 5&#x…