目錄
文章目錄
一、什麼是聚類
1.1 聚類的定義
聚類(Clustering)
是按照某個特定標準(如距離)把一個數據集分割成不同的類或簇,使得同一個簇內的數據對象的相似性儘可能大,同時不在同一個簇中的數據對象的差異性也儘可能地大。也即聚類後同一類的數據儘可能聚集到一起,不同類數據儘量分離。
1.2 聚類和分類的區別
聚類(Clustering)
:是指把相似的數據劃分到一起,具體劃分的時候並不關心這一類的標籤,目標就是把相似的數據聚合到一起,聚類是一種無監督學習(Unsupervised Learning)
方法。分類(Classification)
:是需要標註數據是某種具體的類型,通過訓練數據集獲得一個分類器,再通過分類器去預測未知數據的過程,分類是一種監督學習(Supervised Learning)
方法。
1.3 聚類的一般過程
- 數據準備:特徵標準化和降維
- 特徵選擇:從最初的特徵中選擇最有效的特徵,並將其存儲在向量中
- 特徵提取:通過對選擇的特徵進行轉換形成新的突出特徵
- 聚類:基於某種距離函數進行相似度度量,獲取簇
- 聚類結果評估:分析聚類結果,如
SSE
等
1.4 數據對象間的相似度度量
對於數值型數據,可以使用下表中的相似度度量方法。
相似度度量準則 | 相似度度量函數 |
---|---|
Euclidean 距離 | |
Manhattan 距離 | |
Chebyshev 距離 | |
Minkowski 距離 |
Minkowski
距離就是$ Lp p≥1$),而 Manhattan
距離、Euclidean
距離、Chebyshev
距離分別對應 時的情形。
1.5 cluster之間的相似度度量
除了需要衡量對象之間的距離之外,有些聚類算法(如層次聚類)還需要衡量cluster
之間的距離 ,假設和 爲兩個 cluster
,則前四種方法定義的 和 之間的距離如下表所示:
相似度度量準則 | 相似度度量函數 |
---|---|
Single-link | |
Complete-link | |
UPGMA | |
WPGMA | - |
Single-link
定義兩個cluster
之間的距離爲兩個cluster
之間距離最近的兩個點之間的距離,這種方法會在聚類的過程中產生鏈式效應
,即有可能會出現非常大的cluster
Complete-link
定義的是兩個cluster
之間的距離爲兩個``cluster之間距離最遠的兩個點之間的距離,這種方法可以避免
鏈式效應`,對異常樣本點(不符合數據集的整體分佈的噪聲點)卻非常敏感,容易產生不合理的聚類UPGMA
正好是Single-link
和Complete-link
方法的折中,他定義兩個cluster
之間的距離爲兩個cluster
之間所有點距離的平均值- 最後一種
WPGMA
方法計算的是兩個cluster
之間兩個對象之間的距離的加權平均值,加權的目的是爲了使兩個cluster
對距離的計算的影響在同一層次上,而不受cluster
大小的影響,具體公式和採用的權重方案有關。
二、數據聚類方法
數據聚類方法主要可以分爲劃分式聚類方法(Partition-based Methods)
、基於密度的聚類方法(Density-based methods)
、層次化聚類方法(Hierarchical Methods)
等。
2.1 劃分式聚類方法
劃分式聚類方法需要事先指定簇類的數目或者聚類中心,通過反覆迭代,直至最後達到"簇內的點足夠近,簇間的點足夠遠"的目標。經典的劃分式聚類方法有k-means
及其變體k-means++
、bi-kmeans
、kernel k-means
等。
2.1.2 k-means算法
經典的k-means
算法的流程如下:
- 創建個點作爲初始質心(通常是隨機選擇)
- 當任意一個點的簇分配結果發生改變時
- 對數據集中的每個數據點
- 對每個質心
- 計算質心與數據點之間的距離
- 將數據點分配到距其最近的簇
- 對每個簇,計算簇中所有點的均值並將均值作爲質心
經典k-means
源代碼,下左圖是原始數據集,通過觀察發現大致可以分爲4類,所以取,測試數據效果如下右圖所示。
看起來很順利,但事情並非如此,我們考慮k-means
算法中最核心的部分,假設是數據點,是初始化的數據中心,那麼我們的目標函數可以寫成
這個函數是非凸優化函數,會收斂於局部最優解,可以參考證明過程。舉個🌰,,則
該函數的曲線如下圖所示
可以發現該函數有兩個局部最優點,當時初始質心點取值不同的時候,最終的聚類效果也不一樣,接下來我們看一個具體的實例。
在這個例子當中,下方的數據應該歸爲一類,而上方的數據應該歸爲兩類,這是由於初始質心點選取的不合理造成的誤分。而值的選取對結果的影響也非常大,同樣取上圖中數據集,取,可以得到下面的聚類結果:
一般來說,經典k-means
算法有以下幾個特點:
- 需要提前確定值
- 對初始質心點敏感
- 對異常數據敏感
2.1.2 k-means++算法
k-means++
是針對k-means
中初始質心點選取的優化算法。該算法的流程和k-means
類似,改變的地方只有初始質心的選取,該部分的算法流程如下
- 隨機選取一個數據點作爲初始的聚類中心
- 當聚類中心數量小於
- 計算每個數據點與當前已有聚類中心的最短距離,用表示,這個值越大,表示被選取爲下一個聚類中心的概率越大,最後使用輪盤法選取下一個聚類中心
k-means++
源代碼,使用k-means++
對上述數據做聚類處理,得到的結果如下
2.1.3 bi-kmeans算法
一種度量聚類效果的指標是SSE(Sum of Squared Error)
,他表示聚類後的簇離該簇的聚類中心的平方和,SSE
越小,表示聚類效果越好。 bi-kmeans
是針對kmeans
算法會陷入局部最優的缺陷進行的改進算法。該算法基於SSE最小化的原理,首先將所有的數據點視爲一個簇,然後將該簇一分爲二,之後選擇其中一個簇繼續進行劃分,選擇哪一個簇進行劃分取決於對其劃分是否能最大程度的降低SSE
的值。
該算法的流程如下:
- 將所有點視爲一個簇
- 當簇的個數小於時
- 對每一個簇
- 計算總誤差
- 在給定的簇上面進行
k-means
聚類()- 計算將該簇一分爲二之後的總誤差
- 選取使得誤差最小的那個簇進行劃分操作
bi-kmeans
算法源代碼,利用bi-kmeans
算法處理上節中的數據得到的結果如下圖所示。
這是一個全局最優的方法,所以每次計算出來的SSE
值肯定也是一樣的,我們和前面的k-means
、k-means++
比較一下計算出來的SSE
值
序號 | k-means | k-means++ | bi-kmeans |
---|---|---|---|
1 | 2112 | 120 | 106 |
2 | 388 | 125 | 106 |
3 | 824 | 127 | 106 |
agv | 1108 | 124 | 106 |
可以看到,k-means
每次計算出來的SSE
都較大且不太穩定,k-means++
計算出來的SSE
較穩定並且數值較小,而bi-kmeans
每次計算出來的SSE
都一樣(因爲是全局最優解)並且計算的SSE
都較小,說明聚類的效果也最好。
2.2 基於密度的方法
k-means
算法對於凸性數據具有良好的效果,能夠根據距離來講數據分爲球狀類的簇,但對於非凸形狀的數據點,就無能爲力了,當k-means
算法在環形數據的聚類時,我們看看會發生什麼情況。
從上圖可以看到,kmeans
聚類產生了錯誤的結果,這個時候就需要用到基於密度的聚類方法了,該方法需要定義兩個參數和,分別表示密度的鄰域半徑和鄰域密度閾值。DBSCAN
就是其中的典型。
2.2.1 DBSCAN算法
首先介紹幾個概念,考慮集合,表示定義密度的鄰域半徑,設聚類的鄰域密度閾值爲,有以下定義:
- 鄰域(-neighborhood)
-
密度(desity)
的密度爲
-
核心點(core-point)
設,若,則稱爲的核心點,記中所有核心點構成的集合爲,記所有非核心點構成的集合爲。
- 邊界點(border-point)
若,且,滿足
即的鄰域中存在覈心點,則稱爲的邊界點,記中所有的邊界點構成的集合爲。
此外,邊界點也可以這麼定義:若,且落在某個核心點的鄰域內,則稱爲的一個邊界點,一個邊界點可能同時落入一個或多個核心點的鄰域。
- 噪聲點(noise-point)
若滿足
則稱爲噪聲點。
如下圖所示,設,則A爲核心點,B、C是邊界點,而N是噪聲點。
該算法的流程如下:
- 標記所有對象爲unvisited
- 當有標記對象時
- 隨機選取一個unvisited對象
- 標記爲visited
- 如果的$\varepsilon M$個對象,則
- 創建一個新的簇,並把放入中
- 設是的$\varepsilon Np’$
- 如果點是unvisited
- 標記爲visited
- 如果的$\varepsilon MN$
- 如果還不是任何簇的成員,則把添加到
- 輸出
- 否則標記爲噪聲
構建鄰域的過程可以使用kd-tree
進行優化,循環過程可以使用Numba、Cython、C
進行優化,DBSCAN
的源代碼,使用該節一開始提到的數據集,聚類效果如下
聚類的過程示意圖
當設置不同的時,會產生不同的結果,如下圖所示
當設置不同的時,會產生不同的結果,如下圖所示
一般來說,DBSCAN
算法有以下幾個特點:
- 需要提前確定和值
- 不需要提前設置聚類的個數
- 對初值選取敏感,對噪聲不敏感
- 對密度不均的數據聚合效果不好
2.2.2 OPTICS算法
在DBSCAN
算法中,使用了統一的值,當數據密度不均勻的時候,如果設置了較小的值,則較稀疏的cluster
中的節點密度會小於,會被認爲是邊界點而不被用於進一步的擴展;如果設置了較大的值,則密度較大且離的比較近的cluster
容易被劃分爲同一個cluster
,如下圖所示。
- 如果設置的較大,將會獲得A,B,C這3個
cluster
- 如果設置的較小,將會只獲得C1、C2、C3這3個
cluster
對於密度不均的數據選取一個合適的是很困難的,對於高維數據,由於維度災難(Curse of dimensionality),的選取將變得更加困難。
怎樣解決DBSCAN
遺留下的問題呢?
The basic idea to overcome these problems is to run an algorithm which produces a special order of the database with respect to its density-based clustering structure containing the information about every clustering level of the data set (up to a “generating distance” ), and is very easy to analyze.
即能夠提出一種算法,使得基於密度的聚類結構能夠呈現出一種特殊的順序,該順序所對應的聚類結構包含了每個層級的聚類的信息,並且便於分析。
OPTICS(Ordering Points To Identify the Clustering Structure, OPTICS)
實際上是DBSCAN
算法的一種有效擴展,主要解決對輸入參數敏感的問題。即選取有限個鄰域參數 進行聚類,這樣就能得到不同鄰域參數下的聚類結果。
在介紹OPTICS
算法之前,再擴展幾個概念。
- 核心距離(core-distance)
樣本,對於給定的和,使得成爲核心點的最小鄰域半徑稱爲的核心距離,其數學表達如下
其中,表示在集合中與節點第近鄰的節點,如表示中與最近的節點,如果爲核心點,則必然會有。
- 可達距離(reachability-distance)
設,對於給定的參數,關於的可達距離定義爲
特別地,當爲核心點時,可以按照下式來理解的含義
即表示使得**“爲核心點"且"從直接密度可達”**同時成立的最小鄰域半徑。
可達距離的意義在於衡量所在的密度,密度越大,他從相鄰節點直接密度可達的距離越小,如果聚類時想要朝着數據儘量稠密的空間進行擴張,那麼可達距離最小是最佳的選擇。
舉例,下圖中假設,半徑是。那麼點的核心距離是,點2的可達距離是,點3的可達距離也是,點4的可達距離則是的距離。
OPTICS
源代碼,算法流程如下:
- 標記所有對象爲unvisited,初始化order_list爲空
- 當有標記對象時
- 隨機選取一個unvisited對象
- 標記爲visited,插入結果序列order_list中
- 如果的鄰域內至少有個對象,則
- 初始化seed_list種子列表
- 調用insert_list(),將鄰域對象中未被訪問的節點按照可達距離插入隊列seeld_list中
- 當seed_list列表不爲空
- 按照可達距離升序取出seed_list中第一個元素
- 標記爲visited,插入結果序列order_list中
- 如果的鄰域內至少有個對象,則
- 調用insert_list(),將鄰域對象中未被訪問的節點按照可達距離插入隊列seeld_list中
算法中有一個很重要的insert_list()函數,這個函數如下:
- 對中所有的鄰域點
- 如果未被訪問過
- 計算
- 如果
- 將節點按照可達距離插入seed_list中
- 否則
- 如果
- 更新的值,並按照可達距離重新插入seed_list中
該算法最終獲取知識是一個輸出序列,該序列按照密度不同將相近密度的點聚合在一起,而不是輸出該點所屬的具體類別,如果要獲取該點所屬的類型,需要再設置一個參數提取出具體的類別。這裏我們舉一個例子就知道是怎麼回事了。
隨機生成三組密度不均的數據,我們使用DBSCAN
和OPTICS
來看一下效果。
OPTICS
算法輸出序列的過程:
可見,OPTICS
第一步生成的輸出序列較好的保留了各個不同密度的簇的特徵,根據輸出序列的可達距離圖,再設定一個合理的,便可以獲得較好的聚類效果。
2.3 層次化聚類方法
前面介紹的幾種算法確實可以在較小的複雜度內獲取較好的結果,但是這幾種算法卻存在一個鏈式效應
的現象,比如:A與B相似,B與C相似,那麼在聚類的時候便會將A、B、C聚合到一起,但是如果A與C不相似,就會造成聚類誤差,嚴重的時候這個誤差可以一直傳遞下去。爲了降低鏈式效應
,這時候層次聚類就該發揮作用了。
層次聚類算法 (hierarchical clustering) 將數據集劃分爲一層一層的 clusters
,後面一層生成的 clusters
基於前面一層的結果。層次聚類算法一般分爲兩類:
- Agglomerative 層次聚類:又稱自底向上(bottom-up)的層次聚類,每一個對象最開始都是一個
cluster
,每次按一定的準則將最相近的兩個cluster
合併生成一個新的cluster
,如此往復,直至最終所有的對象都屬於一個cluster
。這裏主要關注此類算法。 - Divisive 層次聚類: 又稱自頂向下(top-down)的層次聚類,最開始所有的對象均屬於一個
cluster
,每次按一定的準則將某個cluster
劃分爲多個cluster
,如此往復,直至每個對象均是一個cluster
。
另外,需指出的是,層次聚類算法是一種貪心算法(greedy algorithm),因其每一次合併或劃分都是基於某種局部最優的選擇。
2.3.1 Agglomerative算法
給定數據集 ,Agglomerative
層次聚類最簡單的實現方法分爲以下幾步:
- 初始時每個樣本爲一個
cluster
,計算距離矩陣 ,其中元素爲樣本點和 之間的距離;- 遍歷距離矩陣 ,找出其中的最小距離(對角線上的除外),並由此得到擁有最小距離的兩個
cluster
的編號,將這兩個cluster
合併爲一個新的cluster
並依據cluster
距離度量方法更新距離矩陣(刪除這兩個cluster
對應的行和列,並把由新cluster
所算出來的距離向量插入 中),存儲本次合併的相關信息;- 重複 2 的過程,直至最終只剩下一個
cluster
。
Agglomerative
算法源代碼,可以看到,該 算法的時間複雜度爲 (由於每次合併兩個 cluster
時都要遍歷大小爲 的距離矩陣來搜索最小距離,而這樣的操作需要進行 次),空間複雜度爲 (由於要存儲距離矩陣)。
上圖中分別使用了層次聚類中4個不同的cluster
度量方法,可以看到,使用single-link
確實會造成一定的鏈式效應,而使用complete-link
則完全不會產生這種現象,使用average-link
和ward-link
則介於兩者之間。
2.4 聚類方法比較
算法類型 | 適合的數據類型 | 抗噪點性能 | 聚類形狀 | 算法效率 |
---|---|---|---|---|
kmeans | 數值型 | 較差 | 球形 | 很高 |
k-means++ | 數值型 | 一般 | 球形 | 較高 |
bi-kmeans | 數值型 | 一般 | 球形 | 較高 |
DBSCAN | 數值型 | 較好 | 任意形狀 | 一般 |
OPTICS | 數值型 | 較好 | 任意形狀 | 一般 |
Ag glomerative | 混合型 | 較好 | 任意形狀 | 較差 |
三、參考文獻
[1] 李航.統計學習方法
[2] Peter Harrington.Machine Learning in Action/李銳.機器學習實戰
[3] https://www.zhihu.com/question/34554321
[4] T. Soni Madhulatha.AN OVERVIEW ON CLUSTERING METHODS
[5] https://zhuanlan.zhihu.com/p/32375430
[6] http://heathcliff.me/聚類分析(一):層次聚類算法
[7] https://www.cnblogs.com/tiaozistudy/p/dbscan_algorithm.html
[8] https://blog.csdn.net/itplus/article/details/10089323
[9] Mihael Ankerst.OPTICS: ordering points to identify the clustering structure