Birch層次聚類(lèi)

Birch層次聚類(lèi)算法

標(biāo)簽(空格分隔): CF樹(shù)建立


主要借鑒的網(wǎng)文地址,并進(jìn)行大量引用:【非常淺顯易懂】
http://www.cnblogs.com/pinard/p/6179132.html 【主要以此文為主】
http://www.cnblogs.com/tiaozistudy/p/6129425.html
根據(jù)上述第二個(gè)網(wǎng)址的步驟,進(jìn)行代碼化的代碼地址:
https://github.com/AresAnt/ML-DL/tree/master/Clustering/Birch

BIRCH算法比較適合于數(shù)據(jù)量大,類(lèi)別數(shù)K也比較多的情況。它運(yùn)行速度很快,只需要單遍掃描數(shù)據(jù)集就能進(jìn)行聚類(lèi),當(dāng)然需要用到一些技巧,下面我們就對(duì)BIRCH算法做一個(gè)總結(jié)。
【個(gè)人建議,如想要自己寫(xiě)CF樹(shù)生成代碼前,請(qǐng)先了解一下B+樹(shù)的構(gòu)造與寫(xiě)法對(duì)之后的代碼完成將會(huì)有幫助?!?/p>

1.聚類(lèi)特征CF與聚類(lèi)特征樹(shù)CF Tree

在聚類(lèi)特征樹(shù)中,一個(gè)聚類(lèi)特征CF是這樣定義的:每一個(gè)CF是一個(gè)三元組,可以用(N,LS,SS)表示。其中N代表了這個(gè)CF中擁有的樣本點(diǎn)的數(shù)量,這個(gè)好理解;LS代表了這個(gè)CF中擁有的樣本點(diǎn)各特征維度的和向量,SS代表了這個(gè)CF中擁有的樣本點(diǎn)各特征維度的平方和。舉個(gè)例子如下圖,在CF Tree中的某一個(gè)節(jié)點(diǎn)的某一個(gè)CF中,有下面5個(gè)樣本(3,4), (2,6), (4,5), (4,7), (3,8)。則它對(duì)應(yīng)的N=5, LS= (3+2+4+4+3,4+6+5+7+8) =(16,30), SS = (32+22+42+42+32+42+62+52+72+82) = (54+190) = 244。具體內(nèi)容可如下所示:



CF有一個(gè)很好的性質(zhì),就是滿足線性關(guān)系,也就是CF1+CF2=(N1+N2,LS1+LS2,SS1+SS2)。這個(gè)性質(zhì)從定義也很好理解。如果把這個(gè)性質(zhì)放在CF Tree上,也就是說(shuō),在CF Tree中,對(duì)于每個(gè)父節(jié)點(diǎn)中的CF節(jié)點(diǎn),它的(N,LS,SS)三元組的值等于這個(gè)CF節(jié)點(diǎn)所指向的所有子節(jié)點(diǎn)的三元組之和。如下圖所示:



從上圖中可以看出,根節(jié)點(diǎn)的CF1的三元組的值,可以從它指向的6個(gè)子節(jié)點(diǎn)(CF7 - CF12)的值相加得到。這樣我們?cè)诟翪F Tree的時(shí)候,可以很高效。

對(duì)于CF Tree,我們一般有幾個(gè)重要參數(shù),第一個(gè)參數(shù)是每個(gè)內(nèi)部節(jié)點(diǎn)的最大CF數(shù)B,第二個(gè)參數(shù)是每個(gè)葉子節(jié)點(diǎn)的最大CF數(shù)L,第三個(gè)參數(shù)是針對(duì)葉子節(jié)點(diǎn)中某個(gè)CF中的樣本點(diǎn)來(lái)說(shuō)的,它是葉節(jié)點(diǎn)每個(gè)CF的最大樣本半徑閾值T,也就是說(shuō),在這個(gè)CF中的所有樣本點(diǎn)一定要在半徑小于T的一個(gè)超球體內(nèi)。對(duì)于上圖中的CF Tree,限定了B=7, L=5, 也就是說(shuō)內(nèi)部節(jié)點(diǎn)最多有7個(gè)CF,而葉子節(jié)點(diǎn)最多有5個(gè)CF。

2.聚類(lèi)特征樹(shù)CF Tree的生成

下面我們看看怎么生成CF Tree。我們先定義好CF Tree的參數(shù): 即內(nèi)部節(jié)點(diǎn)的最大CF數(shù)B, 葉子節(jié)點(diǎn)的最大CF數(shù)L, 葉節(jié)點(diǎn)每個(gè)CF的最大樣本半徑閾值T

在最開(kāi)始的時(shí)候,CF Tree是空的,沒(méi)有任何樣本,我們從訓(xùn)練集讀入第一個(gè)樣本點(diǎn),將它放入一個(gè)新的CF三元組A,這個(gè)三元組的N=1,將這個(gè)新的CF放入根節(jié)點(diǎn),此時(shí)的CF Tree如下圖:


現(xiàn)在我們繼續(xù)讀入第二個(gè)樣本點(diǎn),我們發(fā)現(xiàn)這個(gè)樣本點(diǎn)和第一個(gè)樣本點(diǎn)A,在半徑為T(mén)的超球體范圍內(nèi),也就是說(shuō),他們屬于一個(gè)CF,我們將第二個(gè)點(diǎn)也加入CF A,此時(shí)需要更新A的三元組的值。此時(shí)A的三元組中N=2。此時(shí)的CF Tree如下圖:


此時(shí)來(lái)了第三個(gè)節(jié)點(diǎn),結(jié)果我們發(fā)現(xiàn)這個(gè)節(jié)點(diǎn)不能融入剛才前面的節(jié)點(diǎn)形成的超球體內(nèi),也就是說(shuō),我們需要一個(gè)新的CF三元組B,來(lái)容納這個(gè)新的值。此時(shí)根節(jié)點(diǎn)有兩個(gè)CF三元組A和B,此時(shí)的CF Tree如下圖:


當(dāng)來(lái)到第四個(gè)樣本點(diǎn)的時(shí)候,我們發(fā)現(xiàn)和B在半徑小于T的超球體,這樣更新后的CF Tree如下圖:


那個(gè)什么時(shí)候CF Tree的節(jié)點(diǎn)需要分裂呢?假設(shè)我們現(xiàn)在的CF Tree 如下圖, 葉子節(jié)點(diǎn)LN1有三個(gè)CF, LN2和LN3各有兩個(gè)CF。我們的葉子節(jié)點(diǎn)的最大CF數(shù)L=3。此時(shí)一個(gè)新的樣本點(diǎn)來(lái)了,我們發(fā)現(xiàn)它離LN1節(jié)點(diǎn)最近,因此開(kāi)始判斷它是否在sc1,sc2,sc3這3個(gè)CF對(duì)應(yīng)的超球體之內(nèi),但是很不幸,它不在,因此它需要建立一個(gè)新的CF,即sc8來(lái)容納它。問(wèn)題是我們的L=3,也就是說(shuō)LN1的CF個(gè)數(shù)已經(jīng)達(dá)到最大值了,不能再創(chuàng)建新的CF了,怎么辦?此時(shí)就要將LN1葉子節(jié)點(diǎn)一分為二了。


我們將LN1里所有CF元組中,找到兩個(gè)最遠(yuǎn)的CF做這兩個(gè)新葉子節(jié)點(diǎn)的種子CF,然后將LN1節(jié)點(diǎn)里所有CF sc1, sc2, sc3,以及新樣本點(diǎn)的新元組sc8劃分到兩個(gè)新的葉子節(jié)點(diǎn)上。將LN1節(jié)點(diǎn)劃分后的CF Tree如下圖:


如果我們的內(nèi)部節(jié)點(diǎn)的最大CF數(shù)B=3,則此時(shí)葉子節(jié)點(diǎn)一分為二會(huì)導(dǎo)致根節(jié)點(diǎn)的最大CF數(shù)超了,也就是說(shuō),我們的根節(jié)點(diǎn)現(xiàn)在也要分裂,分裂的方法和葉子節(jié)點(diǎn)分裂一樣,分裂后的CF Tree如下圖:


有了上面這一系列的圖,相信大家對(duì)于CF Tree的插入就沒(méi)有什么問(wèn)題了,總結(jié)下CF Tree的插入:

  1. 從根節(jié)點(diǎn)向下尋找和新樣本距離最近的葉子節(jié)點(diǎn)和葉子節(jié)點(diǎn)里最近的CF節(jié)點(diǎn)
  2. 如果新樣本加入后,這個(gè)CF節(jié)點(diǎn)對(duì)應(yīng)的超球體半徑仍然滿足小于閾值T,則更新路徑上所有的CF三元組,插入結(jié)束。否則轉(zhuǎn)入3.
  3. 如果當(dāng)前葉子節(jié)點(diǎn)的CF節(jié)點(diǎn)個(gè)數(shù)小于閾值L,則創(chuàng)建一個(gè)新的CF節(jié)點(diǎn),放入新樣本,將新的CF節(jié)點(diǎn)放入這個(gè)葉子節(jié)點(diǎn),更新路徑上所有的CF三元組,插入結(jié)束。否則轉(zhuǎn)入4。
  4. 將當(dāng)前葉子節(jié)點(diǎn)劃分為兩個(gè)新葉子節(jié)點(diǎn),選擇舊葉子節(jié)點(diǎn)中所有CF元組里超球體距離最遠(yuǎn)的兩個(gè)CF元組,分布作為兩個(gè)新葉子節(jié)點(diǎn)的第一個(gè)CF節(jié)點(diǎn)。將其他元組和新樣本元組按照距離遠(yuǎn)近原則放入對(duì)應(yīng)的葉子節(jié)點(diǎn)。依次向上檢查父節(jié)點(diǎn)是否也要分裂,如果需要按和葉子節(jié)點(diǎn)分裂方式相同

3.Birch算法流程

如不愿看下列粗糙流程,可以參考:http://www.cnblogs.com/tiaozistudy/p/twostep_cluster_algorithm.html【之前給出的第二個(gè)網(wǎng)站,根據(jù)其步驟進(jìn)行操作】

# 獲取的初始化參數(shù)的值,枝平衡銀子β,葉平衡因子λ,空間閾值T,以及是否
class Birch_Class():

    # 獲取的初始化參數(shù)的值,枝平衡因子β,葉平衡因子λ,空間閾值T,以及是否
    def __init__(self,branch_balance=2,leaf_balance=3,threshold=3,compute_labels=True):
        self.branch_balance = branch_balance
        self.leaf_balance = leaf_balance
        self.threshod = threshold
        self.compute_labels=compute_labels

傳入?yún)?shù):

  • 分支平衡參數(shù): branch_balance
  • 葉子平衡參數(shù): leaf_balance
  • 空間閾值: threshold
    ---以上三者數(shù)據(jù)用來(lái)初始化類(lèi)的基本屬性

1.初始化CF樹(shù)為空樹(shù)(建立一個(gè)TreeNode,每個(gè)TreeNode有N個(gè)CFNode)【N與分支平衡因子與葉平衡因子有關(guān)】
2.逐條導(dǎo)入數(shù)據(jù)(后面統(tǒng)一用簇來(lái)代替),進(jìn)行CF樹(shù)的填充
3.判斷當(dāng)前插入的簇與TreeNode中最近的的CFNode(CF簇),然后篩選出該簇,進(jìn)行同樣的遞歸計(jì)算,直到葉子節(jié)點(diǎn)。

#偽代碼:
    if TreeNode is Leaf:
        find nearest CFNode
    else:
        TreeNode = min(Dist(TreeNode.CFnode,傳進(jìn)來(lái)的簇))

4.到葉子節(jié)點(diǎn)后發(fā)現(xiàn),不滿足葉平衡因子,或計(jì)算的閾值超出了范圍,則進(jìn)行葉節(jié)點(diǎn)分裂。
5.葉節(jié)點(diǎn)分裂后,會(huì)增加分支節(jié)點(diǎn)上的CFNode增加,此時(shí)需要判斷增加CFNode后的TreeNode是否滿足分支平衡因子,如果不滿足則當(dāng)前分支節(jié)點(diǎn)進(jìn)行分裂,同時(shí)上一層的分支節(jié)點(diǎn)進(jìn)行CFNode數(shù)量增加。

#偽代碼:
    # 計(jì)算葉節(jié)點(diǎn)是否要分裂,len(TreeNode)就是指CFNode的數(shù)量
    if len(TreeNode) < leaf_balance or Dist(CFNode,傳入的簇) < threshold:
        TreeNode.add(CFNode)
    else:
        TreeNode.split()
        
        # 分裂后,判斷上一層分支數(shù)量會(huì)不會(huì)超出
        @遞歸的函數(shù) 
        if len(TreeNode.parent) < branch_balance:
            TreeNode.parent.add(TreeNode)
        else:
            TreeNode = TreeNode.parent (開(kāi)始上面的函數(shù)遞歸)
        

6.簇插入到葉子節(jié)點(diǎn)時(shí)候,需要更新當(dāng)前插入路徑下的聚類(lèi)特征值,即L,SS,LS等
7.輸出CF樹(shù),然后可以進(jìn)行優(yōu)化

4.Birch算法小結(jié)

BIRCH算法可以不用輸入類(lèi)別數(shù)K值,這點(diǎn)和K-Means,Mini Batch K-Means不同。如果不輸入K值,則最后的CF元組的組數(shù)即為最終的K,否則會(huì)按照輸入的K值對(duì)CF元組按距離大小進(jìn)行合并。

一般來(lái)說(shuō),BIRCH算法適用于樣本量較大的情況,這點(diǎn)和Mini Batch K-Means類(lèi)似,但是BIRCH適用于類(lèi)別數(shù)比較大的情況,而Mini Batch K-Means一般用于類(lèi)別數(shù)適中或者較少的時(shí)候。BIRCH除了聚類(lèi)還可以額外做一些異常點(diǎn)檢測(cè)和數(shù)據(jù)初步按類(lèi)別規(guī)約的預(yù)處理。但是如果數(shù)據(jù)特征的維度非常大,比如大于20,則BIRCH不太適合,此時(shí)Mini Batch K-Means的表現(xiàn)較好。

對(duì)于調(diào)參,BIRCH要比K-Means,Mini Batch K-Means復(fù)雜,因?yàn)樗枰獙?duì)CF Tree的幾個(gè)關(guān)鍵的參數(shù)進(jìn)行調(diào)參,這幾個(gè)參數(shù)對(duì)CF Tree的最終形式影響很大。

最后總結(jié)下BIRCH算法的優(yōu)缺點(diǎn):

BIRCH算法的主要優(yōu)點(diǎn)有:

1) 節(jié)約內(nèi)存,所有的樣本都在磁盤(pán)上,CF Tree僅僅存了CF節(jié)點(diǎn)和對(duì)應(yīng)的指針。

2) 聚類(lèi)速度快,只需要一遍掃描訓(xùn)練集就可以建立CF Tree,CF Tree的增刪改都很快。

3) 可以識(shí)別噪音點(diǎn),還可以對(duì)數(shù)據(jù)集進(jìn)行初步分類(lèi)的預(yù)處理

BIRCH算法的主要缺點(diǎn)有:

1) 由于CF Tree對(duì)每個(gè)節(jié)點(diǎn)的CF個(gè)數(shù)有限制,導(dǎo)致聚類(lèi)的結(jié)果可能和真實(shí)的類(lèi)別分布不同.

2) 對(duì)高維特征的數(shù)據(jù)聚類(lèi)效果不好。此時(shí)可以選擇Mini Batch K-Means

3) 如果數(shù)據(jù)集的分布簇不是類(lèi)似于超球體,或者說(shuō)不是凸的,則聚類(lèi)效果不好。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 姓名:梁祥學(xué)號(hào):17021210935 【嵌牛導(dǎo)讀】:層次聚類(lèi)方法作為一種能夠在一定程度上將聚類(lèi)過(guò)程顯化的聚類(lèi)方法...
    Leon_66閱讀 3,638評(píng)論 1 2
  • 機(jī)器學(xué)習(xí)是做NLP和計(jì)算機(jī)視覺(jué)這類(lèi)應(yīng)用算法的基礎(chǔ),雖然現(xiàn)在深度學(xué)習(xí)模型大行其道,但是懂一些傳統(tǒng)算法的原理和它們之間...
    在河之簡(jiǎn)閱讀 20,915評(píng)論 4 65
  • 任務(wù)統(tǒng)籌策略,就是給框架內(nèi)的某樣元素,分配一個(gè)新任務(wù),并創(chuàng)造出一個(gè)新產(chǎn)品或者新服務(wù)。 讓我最先想到的一個(gè)事情...
    合肥李風(fēng)麗閱讀 525評(píng)論 0 0
  • 在市區(qū)繁華的商業(yè)街, 我終于開(kāi)了一家小店。 雖然店小卻不影響它的特別, 我要把它打造成同行第一。 光看店的招牌就很...
    關(guān)又韋閱讀 166評(píng)論 4 0
  • 尋一段遠(yuǎn)去,念一份情緣…… 過(guò)往裹挾著愛(ài)戀,情深緣淺,過(guò)往相偕有情調(diào),初心向陽(yáng),初識(shí)清瑩……懷舊!尋回印記里所有的...
    夏秋野菊閱讀 404評(píng)論 0 3

友情鏈接更多精彩內(nèi)容