1. 程式人生 > >聚類分析常用演算法原理:KMeans,DBSCAN, 層次聚類

聚類分析常用演算法原理:KMeans,DBSCAN, 層次聚類

聚類分析是非監督學習的很重要的領域。所謂非監督學習,就是資料是沒有類別標記的,演算法要從對原始資料的探索中提取出一定的規律。而聚類分析就是試圖將資料集中的樣本劃分為若干個不相交的子集,每個子集稱為一個“簇”。下面是sklearn中對各種聚類演算法的比較。
這裡寫圖片描述

KMeans

KMeans演算法在給定一個數k之後,能夠將資料集分成k個“簇”C={C1,C2,,Ck},不論這種分類是否合理,或者是否有意義。演算法需要最小化平方誤差:

E=i=1kxCixμi2(1)
其中μi=1|Ci|xCix是簇Ci的均值向量,或者說是質心。其中xμi2代表每個樣本點到均值點的距離(其實也是範數)。這裡就稍微提一下距離度量。
距離度量最常用的就是閔可夫斯基距離(亦即p範數),即
d
istmk(xi,xj)=(u=1n|xiuxju|p)1/p(2)

當p==2的時候,閔可夫斯基距離即為歐氏距離(2範數)
當p==1的時候,閔可夫斯基距離即為曼哈頓距離(1範數 或者叫 cityblock distance)

以上是對於數值屬性來說的,對於一些離散屬性也有相關的距離的定義。最後在現實中的資料如果要確定合適的距離計算式,可以通過“距離度量學習”來實現。

也就是說上面的式(1)的目的就是我們要找到k個簇,使得在每個簇內,所有的樣本點都儘量靠得比較近。

下面介紹KMeans的基本演算法流程
輸入:樣本資料集D,聚類簇數k
(1) 從樣本中隨機選取k個樣本點作為初始的均值向量{

μ1,μ2,,μk}
(2)迴圈以下幾步直到達到停止條件:
(2.1)令Ci=(1ik)
(2.2)對所有樣本點計算他們到k個均值向量之間的距離,取其中距離最短的距離對應的均值向量的標記作為該點的簇標記,然後將該點加入相應的簇Ci
(2.3)對每一個簇計算他們新的均值向量μi=1|Ci|xCix,如果相比之前的向量有變化,就更新,將其作為新的均值向量,如果沒有變化就不變

可以看出KMeans的基本演算法是很容易理解的,演算法本身也挺簡單,執行較快,所以KMeans可用於非常大型的資料集。但是KMeans也有一些缺點
(1)對初始值敏感。KMeans可能由於初始值選的不同,導致最終結果的不同。我的理解是我們要優化的其實是式(1),但是它很難優化,所以我們採用的是一種貪心演算法,那麼這種演算法就可能掉進區域性最優的坑裡面,所以我們要儘量多選幾個初始值多計算幾次。不過scikit-learn裡面KMeans的演算法的引數裡面有個’init’引數,將其設定成’init = k-means++’可以在初始化均值向量的時候讓他們之間儘量分開。
(2)

對特殊分佈的資料集不能夠得出合理的結果
這裡寫圖片描述
比如上圖,我們希望的結果應該是左圖,但是KMeans只能得出右圖,不能得出我們想要的結果,但是這不是KMeans單獨的缺點,很多聚類演算法對這種情況或者資料分佈是一種長條形等的一類特殊情況效果都不甚理想。這些情況在文章開頭的圖中都有所體現。

總體上KMeans以及它很多聚類演算法對於每一簇資料分佈都是凸的情況效果都很好。
除了KMeans之外,我們還有一些它的變體的演算法比如 Mini Batch K-means 或者Learning Vector Quantization (LVQ)等,在這裡就不再贅述。

密度聚類(DBSCAN)

密度聚類的思想是不同於KMeans的,但是更符合我們人類的思維,基本的思想是通過是否緊密相連來判斷樣本點是否屬於一個簇。代表性的演算法就是DBSCAN,它基於一組鄰域引數(ϵ,MinPts)來表徵某處樣本是否是緊密的。在介紹演算法之前先介紹一些概念。
ϵ-鄰域:即對於樣本點xi,和它的距離在ϵ之內的屬於樣本集D中的點的集合,即Nϵ(xj)={siD|dist(xi,xj)ϵ}

核心物件:若xjϵ-鄰域至少包含MinPts個樣本,即|Nϵ(xj)|MinPts,那麼xj是一個核心物件。其實也就是在核心物件周圍的點相對鄰域引數來說是緻密的。

密度直達與可達:直達的意思是點xj位於點xiϵ-鄰域中。可達的意思是存在這麼一個樣本序列p1,p2,,pnxjp1是直達的,p1p2是直達的,就這樣不斷地藉著這些樣本作為“跳板”,xj可以間接地“跳到”xi

密度相連:對於樣本點