K-Means 分群演算法:
輸入一群資料,以及設定為需要分成 c 群
演算法會先隨便找出 c 個點當作中心點
然後對剩下的每個點都去計算跟這 c 個中心點的距離,來決定要把他們分在哪一群
遞迴是先找出這 c 群中下一個中心點
也就是對每一個點都去計算群內其他點到這個點的距離平方
找出全體的距離平方最短的那個點,就是下一個中心點~
而如果每一群找出來中心點都跟原本一樣,就表示已經找到局部最小值了~
不過 K-Means 比較明顯的問題是,因為只能找出局部最小值,並不一定就是整體最佳解
因此一開始第一個設定的中心點是如何選取的,就顯得非常重要~
K-Means 觀念:http://neural.cs.nthu.edu.tw/jang/books/dcpr/kMeans.asp
K-Means 參考的 Java code:http://mx19841031.javaeye.com/blog/224443
另外註記,WEKA 也有包含 K-Means 的演算法可以使用。
WEKA 的資料格式是 ARFF:http://weka.wikispaces.com/ARFF+(stable+version)
使用 ARFF 檔案的範例:http://weka.wikispaces.com/Use+WEKA+in+your+Java+code#Instances
範例程式碼
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
File f = new File( "G:\\cluster\\bank.arff" ); Instances train = new Instances( new BufferedReader( new FileReader(f))); AddCluster ac = new AddCluster(); SimpleKMeans skm = new SimpleKMeans(); skm.setNumClusters( 3 ); // 設定用 K-Means 要分成 3 群 ac.setClusterer(skm); ac.setInputFormat(train); // 指定輸入資料 System.out.println( "Clustered instances:" ); Instances CI = Filter.useFilter(train, ac); // 執行分群演算法 //System.out.println(clusteredI); // 印出分群結果(同下行的迴圈效果) for ( int i= 0 ; i<CI.numInstances() ; i++) { System.out.println((i+ 1 )+ ": " +CI.instance(i)+ "\t" ); System.out.println( "cluster #:" +CI.instance(i).value(CI.instance(i).numAttributes()- 1 )); } System.out.println( "Centroids:" ); Instances centroids = skm.getClusterCentroids(); System.out.println(centroids); // 印出每群的中心點 |
1 則留言:
感謝您的講解,很不錯的範例程式碼。
張貼留言