Change Dir

          先知cd——熱愛生活是一切藝術的開始

          統計

          留言簿(18)

          積分與排名

          “牛”們的博客

          各個公司技術

          我的鏈接

          淘寶技術

          閱讀排行榜

          評論排行榜

          聚類算法學習筆記(三)——順序聚類

             

          1.    順序聚類

          事實上,將n個對象,聚類到k個聚類中這件事本身是一個NP難問題。熟悉組合數學應該知道這個問題的解事第二類Stirling數:。這樣問題也就出現了,如果k值固定,那么計算還是可行的,如果k值不固定,就要對所有的可能k都進行計算,那運行時間可想而知了。然而并不是所有的可行聚類方案都是合理的,所謂的合理,我理解就是說接近你的聚類目標的,之所以我們要分類,必然有初始動機,那么可以根據這個動機制定可行的聚類方案,這樣,復雜度的問題就回避了。

          順序算法(sequential algorithms)是一種非常簡單的聚類算法,大多數都至少將所有特征向量使用一次或幾次,最后的結果依賴于向量參與算法的順序。這種聚類算法一般是不預先知道聚類數量k的,但有可能給出一個聚類數上界q。本文將主要介紹基本順序算法(Basic Sequential Algorithmic Scheme,BSAS)和其幾個變種,并給出代碼實現。

          首先看BSAS,這個算法方案需要用戶定義參數:不相似性閾值θ和允許的最大聚類數q。算法的基本思想:由于要考慮每個新向量,根據向量到已有聚類的距離,將它分配到一個已有的聚類中,或者一個新生成的聚類中。算法的偽碼描述如下:

          1.       m=1   /*{聚類數量}*/

          2.       Cm={x1}

          3.       For i=2 to N

          4.           Ck: d(xi,Ck)=min1£j£md(xi,Cj)

          5.           If (d(xi,Ck)>Θ) AND (m<q) then

          6.               m=m+1

          7.               Cm={xi}

          8.           Else

          9.               Ck=CkÈ{xi}

          10.           如果需要,更新向量表達

          11.       End {if}

          12.   End {for}

          由上面的描述可以看出BSAS算法對向量順序非常依賴,無論是聚類數量還是聚類本身,不同的向量順序會導致完全不同的聚類結果。另一個影響聚類算法結果的重要因素是閾值θ的選擇,這個值直接影響最終聚類的數量,如果θ太小,就會生成很多不必要的聚類,因為很多情況下向量與聚類的合并條件都受到θ的限制,而如果θ太大,則聚類數量又會不夠。BSAS比較適合致密聚類,其對數據集進行一次掃描,每次迭代中計算當前向量與聚類間的距離,因為最后的聚類數m被認為遠小于N,故BSAS的時間復雜度為O(N)

          由于BSAS算法依賴于q,因此這里介紹一種自動估計聚類數q的簡單方法,該方法也適用于其他的聚類算法,令BSAS(Θ)為具有給定不相似閾值θ的BSAS算法。

          1.       For Θ=a to b step c

          2.          算法BSAS(Θ)執行s,每一次都使用不同的順序表示數據。

          3.          估計聚類數,mΘ作為從sBSAS(Θ)算法得來的最常出現的聚類數。

          4.       Next Θ

          其中ab是數據集的所有向量對的最小和最大不相似級別,c的選擇直接受d(x,C)的影響。

          2. 算法實現

          package util.clustering;

          import java.util.ArrayList;
          import java.util.Collection;
          import java.util.Iterator;
          import java.util.List;

          /**
           * 
          @author Jia Yu
           *
           
          */

          public class BSAS <extends Clusterable<T>> {

              
          /**
               * Basic Sequential Algorithmic Scheme
               * 適用于致密聚類
               
          */

              
              
          public BSAS() {
              }

              
              
          /**
               * Basic Sequential Algorithmic Scheme
               * 考慮樣本空間中每個向量,根據向量到已有的聚類中心的距離,將它分配到一個已有聚類中,或者一個新生成的聚類中。
               * time complexity is O(N)
               * BSAS算法對整個數據集只進行一次掃描。
               * 
          @param points 待聚類的向量
               * 
          @param Phi 用戶定義的不相似性閾值
               * 
          @param q 用戶定義的允許的最大聚類數
               * 
          @return
               
          */

              
          public List<Cluster<T>> cluster(final Collection<T> points,final double Phi,final int q){
                  
          int m = 0;
                  
          int n = points.size();
                  
          double disOfXandCj = 0;
                  
          double disOfXandCk;
                  List
          <T> ptList = new ArrayList<T>(points);
                  Cluster
          <T> C = new Cluster<T>(ptList.get(m));
                  C.addPoint(ptList.get(m));
                  Cluster
          <T> Ck = C;
                  List
          <Cluster<T> > cList = new ArrayList<Cluster<T> >();
                  cList.add(C);
                  
          for(int i=1;i<n;i++){
                      disOfXandCk 
          = Double.MAX_VALUE;
                      Iterator
          <Cluster<T> > cListIt = cList.iterator(); 
                      
          while(cListIt.hasNext()){
                          Cluster
          <T> Cj = cListIt.next();
                          disOfXandCj 
          = getDisOfPointAndCluster(ptList.get(i),Cj);
                          
          if(disOfXandCk > disOfXandCj){
                              disOfXandCk 
          = disOfXandCj;
                              Ck 
          = Cj;
                          }

                      }

                      
          if(disOfXandCk > Phi && m < q){            //不滿足條件,則產生新的聚類
                          m++;
                          Cluster
          <T> cm = new Cluster<T>(ptList.get(i));
                          cm.addPoint(ptList.get(i));
                          cList.add(cm);
                      }

                      
          else{            //滿足條件的將點加入已有聚類,并更新聚類中心
                          if(cList.contains(Ck))
                              cList.remove(Ck);
                          Ck.addPoint(ptList.get(i));
                          
          final T newCenter = Ck.getCenter().centroidOf(Ck.getPoints());
                          Cluster
          <T> tempCluster = new Cluster<T>(newCenter);
                          
          for(int j=0;j<Ck.getPoints().size();j++){
                              tempCluster.addPoint(Ck.getPoints().get(j));
                          }

                          cList.add(tempCluster);
                      }

                  }

                  
          return cList;
              }


              
          /**
               * 選擇不同的測度,有不同的算法。
               * 這里默認dis(x,C)為點到聚類中心的距離。
               
          */

              
          private double getDisOfPointAndCluster(T t, Cluster<T> cj) {
                  
          return t.distanceFrom(cj.getCenter());
              }


          }

          3. 程序框架

                 我的聚類程序主要擴展自Apache Commons Math開源框架,下面是其結構,我簡單加入了Clusterer類作為抽象模板類,使用模板方法模式修改了框架,為后續加入的例如BSAS算法提供模板。

          4. 小結

                 順序算法簡單易實現,對于學習聚類來說是入門的最好選擇,考慮到篇幅的限制,不能將代碼全部發上來,如果有需要可以向我索要,Apache Commons Math框架可以到Apache的網站上下載。另外還有很多介紹不夠詳細,感興趣的朋友可以繼續深入研究BSAS的擴展。

          5. 參考文獻及推薦閱讀

          [1]Pattern Recognition Third Edition, Sergios Theodoridis, Konstantinos Koutroumbas

          [2]模式識別第三版, Sergios Theodoridis, Konstantinos Koutroumbas, 李晶皎, 王愛俠, 張廣源等譯

          posted on 2010-03-06 15:02 changedi 閱讀(4877) 評論(15)  編輯  收藏 所屬分類: 聚類分析

          評論

          # re: 聚類算法學習筆記(三)——順序聚類 2010-03-07 10:04 wycg1984

          你好 能把 這個的代碼發給我嗎 sheliang84@gmail.com 謝謝  回復  更多評論   

          # re: 聚類算法學習筆記(三)——順序聚類 2010-03-07 16:58 changedi

          @wycg1984
          已發送,并附加了相關的代碼,希望能有所幫助。  回復  更多評論   

          # re: 聚類算法學習筆記(三)——順序聚類 2010-03-24 11:22 杜薇

          你好,可以把這個代碼發我一分嗎?謝謝!283532423@qq.com  回復  更多評論   

          # re: 聚類算法學習筆記(三)——順序聚類 2010-05-27 12:23 cuepower

          你好,可以把這個的代碼也發給我一份嗎?angelala508@163.com  回復  更多評論   

          # re: 聚類算法學習筆記(三)——順序聚類 2010-12-28 18:39 change folder

          hi, 能否也發我一份兒~ 麻煩您了~~Thanks fafaisland@gmail.com  回復  更多評論   

          # re: 聚類算法學習筆記(三)——順序聚類 2011-04-26 10:59 劉濤

          你好能否源碼發給我一份
          542754187@qq.com
          謝謝  回復  更多評論   

          # re: 聚類算法學習筆記(三)——順序聚類 2011-05-23 13:19 董詩浩

          寒... JAVA看的不是很懂...

          有木有 C plus plus 或者 純C 的代碼呢?

          謝謝了.....kis2009dsh@vip.qq.com  回復  更多評論   

          # re: 聚類算法學習筆記(三)——順序聚類[未登錄] 2011-05-26 12:57 小愛

          有沒有matlab程序呢?  回復  更多評論   

          # re: 聚類算法學習筆記(三)——順序聚類 2011-05-27 09:19 changedi

          用C寫應該不難~~matlab自帶層次聚類,kmeans,各種聚類網上一搜一大堆~~  回復  更多評論   

          # re: 聚類算法學習筆記(三)——順序聚類 2012-01-09 17:16 王晶

          你好,可以把這個聚類代碼發給我下嗎?謝謝562042760@qq.com  回復  更多評論   

          # re: 聚類算法學習筆記(三)——順序聚類 2012-04-17 21:46 蝴蝶

          您好,能否把這個代碼發我一份呢?謝謝872315480@qq.com  回復  更多評論   

          # re: 聚類算法學習筆記(三)——順序聚類 2012-06-26 13:08 muyefei

          能否把代碼發給我一份,謝謝,muyefei@qq.com  回復  更多評論   

          # re: 聚類算法學習筆記(三)——順序聚類[未登錄] 2012-10-22 14:32 Eric

          可否將代碼發給我一份,謝謝,761989639@qq.com  回復  更多評論   

          # re: 聚類算法學習筆記(三)——順序聚類 2013-02-02 11:49 winwordll

          樓主邏輯清晰,寫的非常清楚,看后收獲極大,看這個學習筆記,真是比看多少聚類算法的網頁都有用  回復  更多評論   

          # re: 聚類算法學習筆記(三)——順序聚類 2013-10-22 16:02 歲月的帆

          您好,能否把這個代碼發我一份呢?謝謝872651253@qq.com   回復  更多評論   

          主站蜘蛛池模板: 芦山县| 玉田县| 楚雄市| 沙雅县| 齐齐哈尔市| 四子王旗| 龙海市| 信宜市| 拉孜县| 潮州市| 社旗县| 高安市| 大化| 阿坝县| 塔河县| 华坪县| 慈利县| 青河县| 巢湖市| 类乌齐县| 南康市| 鄯善县| 漳浦县| 资源县| 靖边县| 北京市| 遂昌县| 开封市| 建水县| 静宁县| 沙湾县| 澳门| 六安市| 洛隆县| 南汇区| 桦川县| 浮山县| 凤翔县| 怀化市| 台安县| 怀安县|