1. 程式人生 > >聚類演算法之BIRCH(Java實現)

聚類演算法之BIRCH(Java實現)

BIRCH(Balanced Iterative Reducing and Clustering using Hierarchies)天生就是為處理超大規模(至少要讓你的記憶體容不下)的資料集而設計的,它可以在任何給定的記憶體下執行。關於BIRCH的更多特點先不介紹,我先講一下演算法的完整實現細節,對演算法的實現過程搞清楚後再去看別人對該演算法的評價才會感受深刻。

你不需要具備B樹的相關知識,我接下來會講得很清楚。

BIRCH演算法的過程就是要把待分類的資料插入一棵樹中,並且原始資料都在葉子節點上。這棵樹看起來是這個樣子:

在這棵樹中有3種類型的節點:Nonleaf、Leaf、MinCluster,Root可能是一種Nonleaf,也可能是一種Leaf。所有的Leaf放入一個雙向連結串列中。每一個節點都包含一個CF值,CF是一個三元組

,其中data point instance的個數,是與資料點同維度的向量,是線性和,是平方和。比如有一個MinCluster裡包含3個數據點(1,2,3),(4,5,6),(7,8,9),則

N=3,

=(1+4+7,2+5+8,3+6+9)=(12,15,18),

=(1+16+49,4+25+64,9+36+81)。 

就拿這個MinCluster為例,我們可以計算它的

簇中心

簇半徑

簇直徑

我們還可以計算兩個簇之間的距離,當然你也可以使用D0,D1,D3等等,不過在這裡我們使用D2。

有意思的是簇中心、簇半徑、簇直徑以及兩簇之間的距離D0到D3都可以由CF來計算,比如

簇直徑

簇間距離,這裡的N,LS和SS是指兩簇合並後大簇的N,LS和SS。所謂兩簇合並只需要兩個對應的CF相加那可

CF1 + CF2 = (N1 + N2 , LS1 + LS2, SS1 + SS2)

每個節點的CF值就是其所有孩子節點CF值之和,以每個節點為根節點的子樹都可以看成 是一個簇。

Nonleaf、Leaf、MinCluster都是有大小限制的,Nonleaf的孩子節點不能超過B個,Leaf最多隻能有L個MinCluster,而一個MinCluster的直徑不能超過T。

演算法起初,我們掃描資料庫,拿到第一個data point instance--(1,2,3),我們建立一個空的Leaf和MinCluster,把點(1,2,3)的id值放入Mincluster,更新MinCluster的CF值為(1,(1,2,3),(1,4,9)),把MinCluster作為Leaf的一個孩子,更新Leaf的CF值為(1,(1,2,3),(1,4,9))。實際上只要往樹中放入一個CF(這裡我們用CF作為Nonleaf、Leaf、MinCluster的統稱),就要更新從Root到該葉子節點的路徑上所有節點的CF值。

當又有一個數據點要插入樹中時,把這個點封裝為一個MinCluster(這樣它就有了一個CF值),把新到的資料點記為CF_new,我們拿到樹的根節點的各個孩子節點的CF值,根據D2來找到CF_new與哪個節點最近,就把CF_new加入那個子樹上面去。這是一個遞迴的過程。遞迴的終止點是要把CF_new加入到一個MinCluster中,如果加入之後MinCluster的直徑沒有超過T,則直接加入,否則譔CF_new要單獨作為一個簇,成為MinCluster的兄弟結點。插入之後注意更新該節點及其所有祖先節點的CF值。

插入新節點後,可能有些節點的孩子數大於了B(或L),此時該節點要分裂。對於Leaf,它現在有L+1個MinCluster,我們要新建立一個Leaf,使它作為原Leaf的兄弟結點,同時注意每新建立一個Leaf都要把它插入到雙向連結串列中。L+1個MinCluster要分到這兩個Leaf中,怎麼分呢?找出這L+1個MinCluster中距離最遠的兩個Cluster(根據D2),剩下的Cluster看離哪個近就跟誰站在一起。分好後更新兩個Leaf的CF值,其祖先節點的CF值沒有變化,不需要更新。這可能導致祖先節點的遞迴分裂,因為Leaf分裂後恰好其父節點的孩子數超過了B。Nonleaf的分裂方法與Leaf的相似,只不過產生新的Nonleaf後不需要把它放入一個雙向連結串列中。如果是樹的根節點要分裂,則樹的高度加1。

CF.java

package birch; public class CF { private int N; private double[] LS; private double[] SS; public CF() { LS=new double[BIRCH.dimen]; SS=new double[BIRCH.dimen]; } // 根據一個data point instance建立一個Clustering Feature public CF(double[] data) { int len = data.length; this.N = 1; this.LS = data; this.SS=new double[len]; for (int i = 0; i < len; i++) this.SS[i] = Math.pow(data[i], 2); } //複製建構函式(深複製) public CF(CF cf){ this.N=cf.getN(); int len=cf.getLS().length; this.LS=new double[len]; this.SS=new double[len]; for(int i=

相關推薦

演算法BIRCHJava實現

BIRCH(Balanced Iterative Reducing and Clustering using Hierarchies)天生就是為處理超大規模(至少要讓你的記憶體容不下)的資料集而設計的,它可以在任何給定的記憶體下執行。關於BIRCH的更多特點先不介紹,我先講一下演算法的完整實現細節,對演算

LeetCode演算法題-SqrtJava實現

這是悅樂書的第158次更新,第160篇原創 01 看題和準備 今天介紹的是LeetCode演算法題中Easy級別的第17題(順位題號是69)。 計算並返回x的平方根,其中x保證為非負整數。 由於返回型別是整數,因此將截斷十進位制數字,並僅返回結果的整數部分。例如: 輸入:4 輸出:2

快取淘汰演算法 —— LFU-AgingJava實現

Java實現,用HashMap儲存關係{key值 : 命中次數與上次命中時間},當需要淘汰某個key值時,呼叫map.remove(key)。 import java.util.*; public class LFUAgingMap<K, V> extend

演算法及其程式碼Spectral Clustering

簡介 文章將介紹譜聚類(spectral clustering)的基本演算法,以及在matlab下的程式碼實現。介紹內容將包括: 從圖分割角度直觀理解譜聚類譜聚類演算法步驟資料以及實現程式碼 本文將不會涉及細節化的證明和推導,如有興趣可參考july大

大資料處理bitmap java實現

 問題提出:M(如10億)個int整數,只有其中N個數重複出現過,讀取到記憶體中並將重複的整數刪除。    問題分析:我們肯定會先想到在計算機記憶體中開闢M個int整型資料陣列,來one bye one讀取M個int型別陣列, 然後在一一比對數值,最後將重複資料的去掉。當然這

一次數獨生成及解題演算法的剖析Java實現

# 數獨生成及求解方案剖析(Java實現) ## **關鍵詞** - 數獨9x9 - 數獨生成 - 數獨解題 --- ## **序言** 最近業務在鞏固Java基礎,編寫了一個基於JavaFX的數獨小遊戲(隨後放連結)。寫到核心部分發現平時玩的數獨這個東西,還真有點意思: **行、列、子宮格**之

基礎算法系列排序演算法-7.希爾排序 並解決hdu 1425問題java實現

       我們從最初的氣泡排序演算法,到上篇文章的折半插入排序演算法,我們一共學習了5種排序演算法,相信以大家的聰明才智肯定都消化了^_^。在本篇文章中,我們又將學習第6種排序演算法——希爾排序演算法。那就讓我們直奔主題吧。 希爾排序  讓我們回想一下直接插入排序演算

3演算法DBSCAN演算法

文章目錄 1.引言 2.`DBSCAN`相關定義 3.`DBSCAN`密度聚類思想 3.1 `DBSCAN`演算法定義 3.2 DBSCAN演算法流程 4.`DBSCAN`演算法實現 4.1 使用`n

用Python開始機器學習10:演算法K均值

我們之前接觸的所有機器學習演算法都有一個共同特點,那就是分類器會接受2個向量:一個是訓練樣本的特徵向量X,一個是樣本實際所屬的型別向量Y。由於訓練資料必須指定其真實分類結果,因此這種機器學習統稱為有監督學習。然而有時候,我們只有訓練樣本的特徵,而對其型別一無所知。這種情況,我

Mahout機器學習平臺演算法詳細剖析含例項分析

第一部分: 學習Mahout必須要知道的資料查詢技能: 學會查官方幫助文件: 解壓用於安裝檔案(mahout-distribution-0.6.tar.gz),找到如下位置,我將該檔案解壓到win7的G盤mahout資料夾下,路徑如下所示: G:\mahout\mahout

從零開始學習演算法Java實現~~~~字串篇~~~判斷兩個字串是否是顛倒字母順序構成的

從今天開始記錄一下學習演算法的例程,貴在堅持! 寫出一個函式 anagram(s, t) 去判斷兩個字串是否是顛倒字母順序構成的 樣例    給出 s="abcd",t="dcab",返回 true 難都係數* 以下是java程式碼實現: public class So

排序演算法——計數排序Java實現

        今天,我來講一講計數排序。計數排序與堆排序快速排序等排序不同,它是一種非比較排序,已經有人證明過,比較排序的時間下界是Ω(nlogn),但這個性質是不適用於計數排序的,因為它不是比較排序。他的時間是線性的。        計數排序假設n個輸入,每個都是介於0

排序演算法——合併排序/歸併排序Java實現

        今天,來講一講合併排序,其實我已經寫了 堆排序 和 快速排序,本來都不想寫這個,但是,當我發現我身邊很多人竟然都不知道這個排序的時候,我震驚了,畢竟,這是一個經典的入門演算法(反正外國貌似是這樣的,根據我看的書和視訊),歷史也十分悠久。下面就來講講這歷史悠久

排序算法入門希爾排序java實現

入門 介紹 插入 一次 變化 shells ngx i++ ava 希爾排序是對插入排序的改進。插入排序是前面元素已經有序了,移動元素是一個一個一次往後移動,當插入的元素比前面排好序的所有元素都小時,則需要將前面所有元素都往後移動。希爾排序有了自己的增量,可以理

排序算法入門快速排序java實現

大小 ava 相對 其余 時間 個數 技術分享 算法 元素交換   快速排序也是一種分治的排序算法。快速排序和歸並排序是互補的:歸並排序將數組分成兩個子數組分別排序,並將有序的子數組歸並以將整個數組排序,會需要一個額外的數組;而快速排序的排序方式是當兩個子數組都有序

求較大整數n的階乘,因為n較大時n的階乘超出了正常型的表示範圍,采用數組進行操作java實現

階乘 大數字package net.yk.mlgorithm; /** * 求較大數的階乘 * @author Administrator * * @param <T> */ public class ArraysMul<T> { public static void

演算法DBSCAN演算法二:高維資料剪枝應用NQ-DBSCAN

一、經典DBSCAN的不足 1.由於“維度災難”問題,應用高維資料效果不佳 2.執行時間在尋找每個點的最近鄰和密度計算,複雜度是O(n2)。當d>=3時,由於BCP等數學問題出現,時間複雜度會急劇上升到Ω(n的四分之三次方)。 二、DBSCAN在高維資料的改進 目前的研究有

演算法DBSCAN演算法之一:經典DBSCAN

DBSCAN是基於密度空間的聚類演算法,與KMeans演算法不同,它不需要確定聚類的數量,而是基於資料推測聚類的數目,它能夠針對任意形狀產生聚類。 1.epsilon-neighborhood epsoiln-neighborhood(簡稱e-nbhd)可理解為密度空間,表示半徑為e

找零問題Java實現——貪心演算法

貪心演算法也稱為貪婪演算法。 下述找零問題應用的方法就是貪心演算法。現在思考,有沒有更好的找零辦法,使找出的硬幣個數更少呢?也就是說,對於找零問題的這個例項,這個解是不是最優的呢?實際上,可以證明,就這些面額的硬幣來說,對於所有正整數的找零金額,貪心演算法都會輸出一個最優解。 貪心演算法在解

LeetCode演算法題-Merge Sorted ArrayJava實現

這是悅樂書的第161次更新,第163篇原創 01 看題和準備 今天介紹的是LeetCode演算法題中Easy級別的第20題(順位題號是88)。給定兩個排序的整數陣列nums1和nums2,將nums2中的元素合併到nums1中,並且作為一個排序的陣列。在nums1和nums2中初始化的元素個數分別為m和