<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Change Dir

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

    統計

    留言簿(18)

    積分與排名

    “牛”們的博客

    各個公司技術

    我的鏈接

    淘寶技術

    閱讀排行榜

    評論排行榜

    聚類算法學習筆記(四)——層次聚類

     

    1.    層次聚類

    層次聚類算法與之前所講的順序聚類有很大不同,它不再產生單一聚類,而是產生一個聚類層次。說白了就是一棵層次樹。介紹層次聚類之前,要先介紹一個概念——嵌套聚類。講的簡單點,聚類的嵌套與程序的嵌套一樣,一個聚類中R1包含了另一個R2,那這就是R2嵌套在R1中,或者說是R1嵌套了R2。具體說怎么算嵌套呢?聚類R1={{x1,x2},{x3},{x4,x5}嵌套在聚類R2={{x1,x2,x3},{x4,x5}}中,但并不嵌套在聚類R3={{x1,x4},{x3},{x2,x5}}中。

    層次聚類算法產生一個嵌套聚類的層次,算法最多包含N步,在第t步,執行的操作就是在前t-1步的聚類基礎上生成新聚類。主要有合并和分裂兩種實現。我這里只講合并,因為前一階段正好課題用到,另外就是合并更容易理解和實現。當然分裂其實就是合并的相反過程。

    g(Ci,Cj)為所有可能的X聚類對的函數,此函數用于測量兩個聚類之間的近鄰性,用t表示當前聚類的層次級別。通用合并算法的偽碼描述如下:

    1.       初始化:

    a)         選擇Â0={{x1},…,{xN}}

    b)        t=0

    2.       重復執行以下步驟:

    a)         t=t+1

    b)        Ât-1中選擇一組(Ci,Cj),滿足

    c)         定義Cq=CiÈCj,并且產生新聚類Ât=(Ât-1-{Ci,Cj})È{Cq}

    直到所有向量全被加入到單一聚類中。

           這一方法在t層時將兩個向量合并,那么這兩個向量在以后的聚類過程中的后繼聚類都是相同的,也就是說一旦它們走到一起,那么以后就不會再分離……(很專一哦O(_)O~)。這也就引出了這個算法的缺點,當在算法開始階段,若出現聚類錯誤,那么這種錯誤將一直會被延續,無法修改。在層次t上,有N-t個聚類,為了確定t+1層上要合并的聚類對,必須考慮(N-t)(N-t-1)/2個聚類對。這樣,聚類過程總共要考慮的聚類對數量就是(N-1)N(N+1)/6,也就是說整個算法的時間復雜度是O(N3)

    舉例來說,如果令X={x1, x2, x3, x4, x5},其中x1=[1, 1]T, x2=[2, 1]T, x3=[5, 4]T, x4=[6, 5]T, x5=[6.5, 6]T。那么合并算法執行的過程可以用下面的圖來表示。

                  P(X)是不相似矩陣

    該算法從核心過程上來講,就是先計算出數據集中向量之間的距離,記為距離矩陣(也叫不相似矩陣)。接著通過不斷的對矩陣更新,完成聚類。矩陣更新算法的偽碼描述如下:

    1.       初始化:

    a)         Â0={{x1},…,{xN}}

    b)        P0=P(X) (距離矩陣)

    c)         t=0

    2.       重復執行以下步驟:

    a)         t=t+1

    b)        合并CiCjCq,這兩個聚類滿足d(Ci,Cj)=minr,s=1,…,N,rsd(Cr,Cs)

    c)         刪除第ij行,第ij列,同時插入新的行和列,新的行列為新合并的類Cq與所有其他聚類之間的距離值

    直到將所有向量合并到一個聚類中

           大家可以看到,層次聚類算法的輸出結果總是一個聚類,這往往不是我們想要的,我們總希望算法在得到我們期望的結果后就停止。那么我們如何控制呢?常用的做法就是為算法限制一個閾值,矩陣更新過程中,總是將兩個距離最近的聚類合并,那么我們只要加入一個閾值判斷,當這個距離大于閾值時,就說明不需要再合并了,此時算法結束。這樣的閾值引入可以很好的控制算法結束時間,將層次截斷在某一層上。

    2. 算法實現

           MATLAB實現了層次聚類算法,基本語句如下:

    1= [1 2;2.5 4.5;2 2;4 1.5;4 2.5] ;
    2= pdist(X,'euclid'); 
    3= linkage(Y,'single'); 
    4= cluster(Z,'cutoff',cutoff);


    MATLAB還有一個簡化的層次聚類版本,一句話搞定

    1= clusterdata(X,cutoff)

     

    Java實現的版本:

     

      1package util;
      2
      3import java.util.*;
      4
      5public class Clusterer {
      6    private List[] clusterList;
      7    DisjointSets ds;
      8    private static final int MAX = Integer.MAX_VALUE;
      9    private int n;
     10    private int cc;
     11
     12    // private double ori[] = {1,2,5,7,9,10};
     13
     14    public Clusterer(int num) {
     15        ds = new DisjointSets(num);
     16        n = num;
     17        cc = n;
     18        clusterList = new ArrayList[num];
     19        for (int i = 0; i < n; i++)
     20            clusterList[i] = new ArrayList();
     21    }

     22
     23    public List[] getClusterList() {
     24        return clusterList;
     25    }

     26
     27    public void setClusterList(List[] clusterList) {
     28        this.clusterList = clusterList;
     29    }

     30
     31    public void output() {
     32        int ind = 1;
     33        for (int i = 0; i < n; i++{
     34            clusterList[ds.find(i)].add(i);
     35        }

     36        for (int i = 0; i < n; i++{
     37            if (clusterList[i].size() != 0{
     38                System.out.print("cluster " + ind + " :");
     39                for (int j = 0; j < clusterList[i].size(); j++{
     40                    System.out.print(clusterList[i].get(j) + " ");
     41                }

     42                System.out.println();
     43                ind++;
     44            }

     45        }

     46    }

     47
     48    /**
     49     * this method provides a hierachical way for clustering data.
     50     * 
     51     * @param r
     52     *            denote the distance matrix
     53     * @param n
     54     *            denote the sample num(distance matrix's row number)
     55     * @param dis
     56     *            denote the threshold to stop clustering
     57     */

     58    public void cluster(double[][] r, int n, double dis) {
     59        int mx = 0, my = 0;
     60        double vmin = MAX;
     61        for (int i = 0; i < n; i++// 尋找最小距離所在的行列
     62            for (int j = 0; j < n; j++{
     63                if (j > i) {
     64                    if (vmin > r[i][j]) {
     65                        vmin = r[i][j];
     66                        mx = i;
     67                        my = j;
     68                    }

     69                }

     70            }

     71        }

     72        if (vmin > dis) {
     73            return;
     74        }

     75        ds.union(ds.find(mx), ds.find(my)); // 將最小距離所在的行列實例聚類合并
     76        double o1[] = r[mx];
     77        double o2[] = r[my];
     78        double v[] = new double[n];
     79        double vv[] = new double[n];
     80        for (int i = 0; i < n; i++{
     81            double tm = Math.min(o1[i], o2[i]);
     82            if (tm != 0)
     83                v[i] = tm;
     84            else
     85                v[i] = MAX;
     86            vv[i] = MAX;
     87        }

     88        r[mx] = v;
     89        r[my] = vv;
     90        for (int i = 0; i < n; i++// 更新距離矩陣
     91            r[i][mx] = v[i];
     92            r[i][my] = vv[i];
     93        }

     94        cluster(r, n, dis); // 繼續聚類,遞歸直至所有簇之間距離小于dis值
     95    }

     96
     97    /**
     98     * 
     99     * @param r
    100     * @param cnum
    101     *            denote the number of final clusters
    102     */

    103    public void cluster(double[][] r, int cnum) {
    104        /*if(cc< cnum)
    105            System.err.println("聚類數大于實例數");*/

    106        while (cc > cnum) {// 繼續聚類,循環直至聚類個數等于cnum
    107            int mx = 0, my = 0;
    108            double vmin = MAX;
    109            for (int i = 0; i < n; i++// 尋找最小距離所在的行列
    110                for (int j = 0; j < n; j++{
    111                    if (j > i) {
    112                        if (vmin > r[i][j]) {
    113                            vmin = r[i][j];
    114                            mx = i;
    115                            my = j;
    116                        }

    117                    }

    118                }

    119            }

    120            ds.union(ds.find(mx), ds.find(my)); // 將最小距離所在的行列實例聚類合并
    121            double o1[] = r[mx];
    122            double o2[] = r[my];
    123            double v[] = new double[n];
    124            double vv[] = new double[n];
    125            for (int i = 0; i < n; i++{
    126                double tm = Math.min(o1[i], o2[i]);
    127                if (tm != 0)
    128                    v[i] = tm;
    129                else
    130                    v[i] = MAX;
    131                vv[i] = MAX;
    132            }

    133            r[mx] = v;
    134            r[my] = vv;
    135            for (int i = 0; i < n; i++// 更新距離矩陣
    136                r[i][mx] = v[i];
    137                r[i][my] = vv[i];
    138            }

    139            cc--;
    140        }

    141    }

    142
    143    public static void main(String args[]) {
    144        double[][] r = 014689 }103578 },
    145                430245 }652023 },
    146                874201 }985310 } }
    ;
    147        Clusterer cl = new Clusterer(6);
    148        //cl.cluster(r, 6, 1);
    149        cl.cluster(r, 3);
    150        cl.output();
    151    }

    152
    153}

    154


    3. 小結

           層次聚類算法是非常常用的聚類算法,同時也是被廣泛研究的聚類算法。層次聚類本身分為合并和分裂兩種實現,在合并算法中,又分基于矩陣理論的合并和基于圖論的合并。本文只是初學聚類的一點體會,因此只實現了基于矩陣理論的算法,同時,用于大數據集合的層次算法如CUREROCKChameleon算法都沒有涉及,這些算法如果以后有時間,會整理發布。還有截斷點的選擇,最佳聚類數的確定都是可以研究的問題。

    4. 參考文獻及推薦閱讀

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

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



    PS,第四第五節的內容的代碼地址:

    http://www.kuaipan.cn/index.php?ac=fileview&dirid=50160446308614332


    posted on 2010-03-19 20:08 changedi 閱讀(13753) 評論(23)  編輯  收藏 所屬分類: 聚類分析

    評論

    # re: 聚類算法學習筆記(四)——層次聚類 2010-03-20 10:40 路人甲

    哈哈,我這幾天也在學聚類,樓主的博客寫的不錯!  回復  更多評論   

    # re: 聚類算法學習筆記(四)——層次聚類 2010-03-22 15:53 changedi

    @路人甲
    大家可以共同探討~~  回復  更多評論   

    # re: 聚類算法學習筆記(四)——層次聚類 2010-04-22 00:00 劉賀

    你好,能給我發一份源碼嗎?拜托!hebeigeng@126.com  回復  更多評論   

    # re: 聚類算法學習筆記(四)——層次聚類 2010-04-22 12:50 changedi

    @劉賀
    已發送,附帶并查集的實現。  回復  更多評論   

    # re: 聚類算法學習筆記(四)——層次聚類[未登錄] 2010-05-02 10:35 緣來如此

    我現在正在學習聚類算法,能發一份到我的郵箱嗎?謝謝。dowell_2008@live.cn  回復  更多評論   

    # re: 聚類算法學習筆記(四)——層次聚類 2010-06-15 16:25 Meccas

    麻煩您可以發一份源碼給我嗎?我的郵箱是zhaozeyu1@yahoo.cn,最近在寫聚類算法的論文,但是苦于手中沒有源碼,看到您的文章,寫的太好了。不知可以嗎?  回復  更多評論   

    # re: 聚類算法學習筆記(四)——層次聚類 2010-06-21 18:50 王虎虎

    @changedi
    您好,請問您可以給我發個完整的源碼么,您給出的這個代碼里面沒有DisjointSets類的實現,我自己想寫出來,可惜不行,呵呵,我擅長c/c++,對java不很了解,哎,最近一直在研究層次聚類算法,謝謝您!  回復  更多評論   

    # re: 聚類算法學習筆記(四)——層次聚類 2010-06-21 18:54 王虎虎

    您好!
    能否給我發一份您完整的源代碼,您上面給出的那個代碼缺少DisjointSets類的實現,我自己補寫了好幾天還是沒搞定,擺脫您了,我的郵箱是tjnuwanghu@163.com,
    tel:13752311612。
    謝謝您!  回復  更多評論   

    # re: 聚類算法學習筆記(四)——層次聚類 2010-06-22 14:22 王虎虎

    @劉賀
    您好!
    您那有樓主給的層次聚類的java實現代碼么?我也最近在做這方面的研究,生物信息方向的,我對java不是很了解,想看看,完了后轉成c++的。謝謝您啊!

    請您給我也發一份吧:
    Email:tjnuwanghu@163.com
    TEL:137+5231+1612
      回復  更多評論   

    # re: 聚類算法學習筆記(四)——層次聚類 2010-06-25 23:08 王虎虎

    @王虎虎
    package util;
    /**
    * 并查集簡單實現
    * @author Jia Yu
    *
    */
    public class DisjointSets
    {
    public DisjointSets( int numElements )
    {
    s = new int [ numElements ];
    for( int i = 0; i < s.length; i++ )
    s[ i ] = -1;
    }

    public void union( int root1, int root2 )
    {
    assertIsRoot( root1 );
    assertIsRoot( root2 );
    if( root1 == root2 )
    throw new IllegalArgumentException( "Union: root1 == root2 " + root1 );

    if( s[ root2 ] < s[ root1 ] )
    s[ root1 ] = root2;
    else
    {
    if( s[ root1 ] == s[ root2 ] )
    s[ root1 ]--;
    s[ root2 ] = root1;
    }
    }

    public int find( int x )
    {
    assertIsItem( x );
    if( s[ x ] < 0 )
    return x;
    else
    return s[ x ] = find( s[ x ] );
    }

    private int [ ] s;


    private void assertIsRoot( int root )
    {
    assertIsItem( root );
    if( s[ root ] >= 0 )
    throw new IllegalArgumentException( "Union: " + root + " not a root" );
    }

    private void assertIsItem( int x )
    {
    if( x < 0 || x >= s.length )
    throw new IllegalArgumentException( "Disjoint sets: " + x + " not an item" );
    }

    }
      回復  更多評論   

    # re: 聚類算法學習筆記(四)——層次聚類 2010-07-06 07:46 馬雷

    劉賀,你好!
    您那有層次聚類的java實現代碼嗎?我也最近在做這方面的學習,請你給我發送一份吧,郵箱793125322@qq.com  回復  更多評論   

    # re: 聚類算法學習筆記(四)——層次聚類[未登錄] 2011-08-09 13:32 jiajia

    樓主,您好。
    我也最近在做這方面的研究,對java不是很了解,方便發一份完整代碼么,謝謝。
    278164822@qq.com  回復  更多評論   

    # re: 聚類算法學習筆記(四)——層次聚類 2011-10-03 15:31 www

    你好,最近剛學習聚類,能發送一份java源碼嗎?謝謝。wwwsd@live.cn  回復  更多評論   

    # re: 聚類算法學習筆記(四)——層次聚類 2012-08-06 17:34 smallmood

    樓主,你好!層次聚類總結的真好,最近在研究chameleon,想問一下,有沒有關于chameleon的資料,如果有的話,能給我發一份嗎?算法、matlab實現等等都可以,謝啦!sjiezz@163.com  回復  更多評論   

    # re: 聚類算法學習筆記(四)——層次聚類 2012-10-24 17:16 changedi

    我把代碼發鏈接出來,需要的下載就好http://www.kuaipan.cn/index.php?ac=fileview&dirid=50160446308614332  回復  更多評論   

    # re: 聚類算法學習筆記(四)——層次聚類 2012-12-10 21:09 香草可樂

    樓主,你寫的好棒,你發布的那個連接沒有下載的文件喔,能發給我一份源代碼么,萬分感謝!!420164881@qq.com  回復  更多評論   

    # re: 聚類算法學習筆記(四)——層次聚類[未登錄] 2013-01-14 16:53 白樺林

    樓主你好 能給我發份完整的代碼嗎 感激不盡 1028122036@qq.com  回復  更多評論   

    # re: 聚類算法學習筆記(四)——層次聚類[未登錄] 2013-01-14 16:54 白樺林

    對不起 郵箱寫錯了 是1028142036@qq.com  回復  更多評論   

    # re: 聚類算法學習筆記(四)——層次聚類[未登錄] 2013-02-27 17:26 笑笑

    不知問您一下 您的這個代碼可以進行短文本聚類嗎?或者是詞聚類  回復  更多評論   

    # re: 聚類算法學習筆記(四)——層次聚類[未登錄] 2013-02-27 17:50 笑笑

    你知道是否能對短文本聚類呢?@香草可樂
      回復  更多評論   

    # re: 聚類算法學習筆記(四)——層次聚類[未登錄] 2013-02-28 09:22 changedi

    當然可以,詞匯作為空間節點,詞匯相似度作為相似測度(節點距離)@笑笑
      回復  更多評論   

    # re: 聚類算法學習筆記(四)——層次聚類 2013-07-25 10:40 zack

    看了一下 這貨不是貪心么 跟哈弗曼樹差不多啊  回復  更多評論   

    # re: 聚類算法學習筆記(四)——層次聚類 2013-10-22 17:27 歲月的帆

    貌似進不去啊@changedi
    麻煩發給我郵件吧 872651253@qq.com 謝謝  回復  更多評論   

    主站蜘蛛池模板: 一级中文字幕免费乱码专区| 91精品国产免费网站| 亚洲综合另类小说色区| 久久国产精品成人片免费| 亚洲一线产品二线产品| 亚洲综合激情另类专区| 麻豆高清免费国产一区| 午夜亚洲乱码伦小说区69堂| 久久亚洲精品成人777大小说| 成人激情免费视频| 成人无码a级毛片免费| 亚洲偷自拍另类图片二区| 亚洲熟妇无码乱子AV电影| 好大好硬好爽免费视频| 国内精品免费久久影院| 亚洲欧洲无码一区二区三区| 亚洲成A人片777777| 国产网站免费观看| 91在线手机精品免费观看| 色老头综合免费视频| 亚洲精品天堂在线观看| 久热综合在线亚洲精品| 免费日韩在线视频| 美女网站免费福利视频| 国产婷婷成人久久Av免费高清 | 国产久爱免费精品视频| 亚洲一区在线免费观看| 亚洲成A人片777777| 五月婷婷亚洲综合| 四虎影院免费视频| 亚洲日本在线免费观看| 在线涩涩免费观看国产精品| 亚洲AV网一区二区三区 | 亚洲第一永久在线观看| 亚洲熟妇无码另类久久久| 午夜网站免费版在线观看| 亚洲视频在线免费播放| 羞羞视频免费网站在线看| 苍井空亚洲精品AA片在线播放| 亚洲H在线播放在线观看H| 亚洲日本中文字幕|