k均值聚類演算法的java實現,k均值聚類演算法例子

本文目錄一覽:

k-means聚類演算法的java代碼實現文本聚類

K-MEANS演算法:

k-means 演算法接受輸入量 k ;然後將n個數據對象劃分為 k個聚類以便使得所獲得的聚類滿足:同一聚類中的對象相似度較高;而不同聚類中的對象相似度較小。聚類相似度是利用各聚類中對象的均值所獲得一個「中心對象」(引力中心)來進行計算的。

k-means 演算法的工作過程說明如下:首先從n個數據對象任意選擇 k 個對象作為初始聚類中心;而對於所剩下其它對象,則根據它們與這些聚類中心的相似度(距離),分別將它們分配給與其最相似的(聚類中心所代表的)聚類;然後再計算每個所獲新聚類的聚類中心(該聚類中所有對象的均值);不斷重複這一過程直到標準測度函數開始收斂為止。一般都採用均方差作為標準測度函數. k個聚類具有以下特點:各聚類本身儘可能的緊湊,而各聚類之間儘可能的分開。

具體如下:

輸入:k, data[n];

(1) 選擇k個初始中心點,例如c[0]=data[0],…c[k-1]=data[k-1];

(2) 對於data[0]….data[n], 分別與c[0]…c[n-1]比較,假定與c[i]差值最少,就標記為i;

(3) 對於所有標記為i點,重新計算c[i]=/標記為i的個數;

(4) 重複(2)(3),直到所有c[i]值的變化小於給定閾值。

演算法實現起來應該很容易,就不幫你編寫代碼了。

K均值聚類

k均值聚類演算法是一種迭代求解的聚類分析演算法,其步驟是,預將數據分為K組,則隨機選取K個對象作為初始的聚類中心,然後計算每個對象與各個種子聚類中心之間的距離,把每個對象分配給距離它最近的聚類中心。

聚類中心以及分配給它們的對象就代表一個聚類。每分配一個樣本,聚類的聚類中心會根據聚類中現有的對象被重新計算。

這個過程將不斷重複直到滿足某個終止條件。終止條件可以是沒有(或最小數目)對象被重新分配給不同的聚類,沒有(或最小數目)聚類中心再發生變化,誤差平方和局部最小。

k均值聚類是最著名的劃分聚類演算法,由於簡潔和效率使得他成為所有聚類演算法中最廣泛使用的。給定一個數據點集合和需要的聚類數目k,k由用戶指定,k均值演算法根據某個距離函數反覆把數據分入k個聚類中。

聚類演算法,K-means演算法的Java代碼實現

這得分詞+vsm+k-means啊。k-means演算法網上應該不少,但是對文檔的話,還得進行分詞,構建矢量空間模型才能進行聚類啊。

k-means演算法怎麼為對稱矩陣進行聚類?

幾種典型的聚類融合演算法:

1.基於超圖劃分的聚類融合演算法

(1)Cluster-based Similarity Partitioning Algorithm(GSPA)

(2)Hyper Graph-Partitioning Algorithm(HGPA)

(3)Meta-Clustering Algorithm(MCLA)

2.基於關聯矩陣的聚類融合演算法

Voting-K-Means演算法。

3.基於投票策略的聚類融合演算法

w-vote是一種典型的基於加權投票的聚類融合演算法。

同時還有基於互信息的聚類融合演算法和基於有限混合模型的聚類融合演算法。

二、基於關聯矩陣的聚類融合演算法——Voting-K-Means演算法

Voting-K-Means演算法是一種基於關聯矩陣的聚類融合演算法,關聯矩陣的每一行和每一列代表一個數據點,關聯矩陣的元素表示數據集中數據點對共同出現在同一個簇中的概率。

演算法過程:

1.在一個數據集上得到若干個聚類成員;

2.依次掃描這些聚類成員,如果數據點i和j在某個聚類成員中被劃分到同一個簇中,那麼就在關聯矩陣對應的位置計數加1;關聯矩陣中的元素值越大,說明該元素對應的兩個數據點被劃分到同一個簇中的概率越大;

3.得到關聯矩陣之後,Voting-K-Means演算法依次檢查關聯矩陣中的每個元素,如果它的值大於演算法預先設定的閥值,就把這個元素對應的兩個數據點劃分到同一個簇中。

Voting-K-Means演算法的優缺點:

Voting-K-Means演算法不需要設置任何參數,在聚類融合的過程中可以自動地的選擇簇的個數 並且可以處理任意形狀的簇。因為Voting-K-Means演算法在聚類融合過程中是根據兩個數據點共同出現在同一個簇中的可能性大小對它們進行劃分的,所以只要兩個數據點距離足夠近,它們就會被劃分到一個簇中。

Voting-K-Means演算法的缺點是時間複雜度較高,它的時間複雜度是O(n^2);需要較多的聚類成員,如果聚類成員達不到一定規模,那麼關聯矩陣就不能準確反映出兩個數據點出現在同一個簇的概率。

package clustering;import java.io.FileWriter;import weka.clusterers.ClusterEvaluation;import weka.clusterers.SimpleKMeans;import weka.core.DistanceFunction;import weka.core.EuclideanDistance;import weka.core.Instances;import weka.core.converters.ConverterUtils.DataSource;import weka.filters.unsupervised.attribute.Remove;public class Votingkmeans2 extends SimpleKMeans { /** 生成的序列號 */ private static final long serialVersionUID = 1557181390469997876L; /** 劃分的簇數 */ private int m_NumClusters; /** 每個劃分的簇中的實例的數量 */ public int[] m_ClusterSizes; /** 使用的距離函數,這裡是歐幾里德距離 */ protected DistanceFunction m_DistanceFunction = new EuclideanDistance(); /** 實例的簇號賦值 */ protected int[] m_Assignments; /** 設定聚類成員融合閥值 */ private final static double THREASOD = 0.5; /** 生成一個聚類器 */ public void buildClusterer(Instances data) throws Exception{ final int numinst = data.numInstances(); // 數據集的大小 double [][]association = new double[numinst][numinst]; // 定義並初始化一個關聯矩陣 int numIteration = 40; // 設置生成的聚類成員數 final int k = (int)Math.sqrt(numinst); // 設置K-Means聚類演算法參數——簇數 for(int i = 0; i numIteration; i++) { if(data.classIndex() == -1) data.setClassIndex(data.numAttributes() – 1); // 索引是從0開始 String[] filteroption = new String[2]; filteroption[0] = “-R”; filteroption[1] = String.valueOf(data.classIndex() + 1);// 索引是從1開始 Remove remove = new Remove(); remove.setOptions(filteroption); remove.setInputFormat(data); /* 使用過濾器模式生成新的數據集;新數據集是去掉類標籤之後的數據集 */ Instances newdata = weka.filters.Filter.useFilter(data, remove); /* 生成一個K-Means聚類器 */ SimpleKMeans sm = new SimpleKMeans(); sm.setNumClusters(k); sm.setPreserveInstancesOrder(true); // 保持數據集實例的原始順序 sm.setSeed(i); // 通過設置不同的種子,設置不同的簇初始中心點,從而得到不同的聚類結果 sm.buildClusterer(newdata); int[] assigm = sm.getAssignments(); // 得到數據集各個實例的賦值 /* 建立關聯矩陣 */ for(int j = 0; j numinst; j++) { for(int m = j; m numinst; m++) { if(assigm[j] == assigm[m]) { association[j][m] = association[j][m] + 1.0 / numIteration ; } } } } System.out.println(); /* 將生成的關聯矩陣寫入.txt文件(註:生成的txt文本文件在e:/result.txt中) */ FileWriter fw = new FileWriter(“e://result.txt”); for(int j = 0; j numinst; j++) { for(int m = j; m numinst; m++) { //由於關聯矩陣是對稱的,為了改進演算法的效率,只計算矩陣的上三角 String number = String.format(“%8.2f”, association[j][m]); fw.write(number); } fw.write(“\n”); } /* 處理關聯矩陣,分別考慮了兩種情況 :1.關聯矩陣中某個元素對應的兩個數據點已經被劃分到了不同的簇中 * 2.兩個數據點中有一個或者兩個都沒有被劃分到某個簇中。 */ int[] flag = new int[numinst]; int[] flagk = new int[k]; int[] finallabel = new int[numinst]; for(int m = 0; m numinst; m++) { for(int n = m; n numinst; n++) { if(association[m][n] THREASOD) { if(flag[m] == 0 flag[n] == 0) { // 兩個數據點都沒有被劃分到某個簇中, int i = 0; // 將他們劃分到同一個簇中即可 while (i k flagk[i] == 1) i = i + 1; finallabel[m] = i; finallabel[n] = i; flag[m] = 1; flag[n] = 1; flagk[i] = 1; } else if (flag[m] == 0 flag[n] == 1) { // 兩個數據點中有一個沒有被劃分到某個簇中, finallabel[m] = finallabel[n]; // 將他們劃分到同一個簇中即可 flag[m] = 1; } else if (flag[m] == 1 flag[n] == 0) { finallabel[n] = finallabel[m]; flag[n] = 1; } else if (flag[m] == 1 flag[n] == 1 finallabel[m] != finallabel[n]) { // 兩個數據點已被劃分到了不同的簇中, flagk[finallabel[n]] = 0; // 將它們所在的簇合併 int temp = finallabel[n]; for(int i = 0; i numinst; i++) { if(finallabel[i] == temp) finallabel[i] = finallabel[m]; } } } } } m_Assignments = new int[numinst]; System.out.println(“基於關聯矩陣的聚類融合演算法——Voting-K-Means演算法的最終聚類結果”); for(int i = 0; i numinst; i++) { m_Assignments[i] = finallabel[i]; System.out.print(finallabel[i] + ” “); if((i+1) % 50 == 0) System.out.println(); } for(int i = 0; i k; i++) { if(flagk[i] == 1) m_NumClusters++; } } /** * return a string describing this clusterer * * @return a description of the clusterer as a string */ public String toString() { return “Voting-KMeans\n”; } public static void main(String []args) { try {String filename=”e://weka-data//iris.arff”; Instances data = DataSource.read(filename); Votingkmeans2 vk = new Votingkmeans2(); vk.buildClusterer(data); /* 要生成Voting-K-Means的聚類評估結果包括準確率等需要覆蓋重寫toString()方法; * 因為沒有覆蓋重寫,所以這裡生產的評估結果沒有具體內容。 */ ClusterEvaluation eval = new ClusterEvaluation(); eval.setClusterer(vk); eval.evaluateClusterer(new Instances(data)); System.out.println(eval.clusterResultsToString()); } catch (Exception e) { e.printStackTrace(); }}}

分析代碼時注意:得到的類成員變數m_Assignments就是最終Voting-K-Means聚類結果;由於是採用了開源機器學習軟體Weka中實現的SimpleKMeans聚類演算法,初始時要指定簇的個數,這裡是數據集大小開根號向下取整;指定的閥值為0.5,即當關聯矩陣元素的值大於閥值時,才對該元素對應的兩個數據點進行融合,劃分到一個簇中,考慮兩種情況,代碼注釋已有,這裡不再詳述。但聚類融合的實驗結果並不理想,鶯尾花數據集irsi.arff是數據挖掘實驗中最常用的數據集,原數據集共有三個類;但本實驗進行四十個聚類成員的融合,其最終聚類結果劃分成兩個簇;其原因可能有兩個:一是演算法本身的問題,需要使用其他更加優化的聚類融合演算法;二是實現上的問題,主要就在聚類結果的融合上,需要進行一步對照關聯矩陣進行邏輯上的分析,找出代碼中的問題。關聯矩陣文本文件

———————

本文來自 Turingkk 的CSDN 博客 ,全文地址請點擊:

原創文章,作者:TRMR,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/140708.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
TRMR的頭像TRMR
上一篇 2024-10-04 00:24
下一篇 2024-10-04 00:24

相關推薦

  • Java JsonPath 效率優化指南

    本篇文章將深入探討Java JsonPath的效率問題,並提供一些優化方案。 一、JsonPath 簡介 JsonPath是一個可用於從JSON數據中獲取信息的庫。它提供了一種DS…

    編程 2025-04-29
  • java client.getacsresponse 編譯報錯解決方法

    java client.getacsresponse 編譯報錯是Java編程過程中常見的錯誤,常見的原因是代碼的語法錯誤、類庫依賴問題和編譯環境的配置問題。下面將從多個方面進行分析…

    編程 2025-04-29
  • 蝴蝶優化演算法Python版

    蝴蝶優化演算法是一種基於仿生學的優化演算法,模仿自然界中的蝴蝶進行搜索。它可以應用於多個領域的優化問題,包括數學優化、工程問題、機器學習等。本文將從多個方面對蝴蝶優化演算法Python版…

    編程 2025-04-29
  • Java Bean載入過程

    Java Bean載入過程涉及到類載入器、反射機制和Java虛擬機的執行過程。在本文中,將從這三個方面詳細闡述Java Bean載入的過程。 一、類載入器 類載入器是Java虛擬機…

    編程 2025-04-29
  • Java騰訊雲音視頻對接

    本文旨在從多個方面詳細闡述Java騰訊雲音視頻對接,提供完整的代碼示例。 一、騰訊雲音視頻介紹 騰訊雲音視頻服務(Cloud Tencent Real-Time Communica…

    編程 2025-04-29
  • Java Milvus SearchParam withoutFields用法介紹

    本文將詳細介紹Java Milvus SearchParam withoutFields的相關知識和用法。 一、什麼是Java Milvus SearchParam without…

    編程 2025-04-29
  • Python實現爬樓梯演算法

    本文介紹使用Python實現爬樓梯演算法,該演算法用於計算一個人爬n級樓梯有多少種不同的方法。 有一樓梯,小明可以一次走一步、兩步或三步。請問小明爬上第 n 級樓梯有多少種不同的爬樓梯…

    編程 2025-04-29
  • Java 8中某一周的周一

    Java 8是Java語言中的一個版本,於2014年3月18日發布。本文將從多個方面對Java 8中某一周的周一進行詳細的闡述。 一、數組處理 Java 8新特性之一是Stream…

    編程 2025-04-29
  • AES加密解密演算法的C語言實現

    AES(Advanced Encryption Standard)是一種對稱加密演算法,可用於對數據進行加密和解密。在本篇文章中,我們將介紹C語言中如何實現AES演算法,並對實現過程進…

    編程 2025-04-29
  • Java判斷字元串是否存在多個

    本文將從以下幾個方面詳細闡述如何使用Java判斷一個字元串中是否存在多個指定字元: 一、字元串遍歷 字元串是Java編程中非常重要的一種數據類型。要判斷字元串中是否存在多個指定字元…

    編程 2025-04-29

發表回復

登錄後才能評論