數據挖掘—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.pswp.cn/news/392079.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/392079.shtml
英文地址,請注明出處:http://en.pswp.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…