20分鐘學會DBSCAN聚類演算法

枫树湾河桥發表於2024-07-16

原文連結: https://cloud.tencent.com/developer/article/1664886

DBSCAN是一種非常著名的基於密度的聚類演算法。其英文全稱是 Density-Based Spatial Clustering of Applications with Noise,意即:一種基於密度,對噪聲魯棒的空間聚類演算法。直觀效果上看,DBSCAN演算法可以找到樣本點的全部密集區域,並把這些密集區域當做一個一個的聚類簇。

DBSCAN演算法具有以下特點:

  • 基於密度,對遠離密度核心的噪聲點魯棒
  • 無需知道聚類簇的數量
  • 可以發現任意形狀的聚類簇

DBSCAN通常適合於對較低維度資料進行聚類分析。

公眾號後臺回覆關鍵字:"原始碼",獲取本文全部程式碼和對應插圖PPT。

一,基本概念

DBSCAN的基本概念可以用1,2,3,4來總結。

1個核心思想:基於密度。

直觀效果上看,DBSCAN演算法可以找到樣本點的全部密集區域,並把這些密集區域當做一個一個的聚類簇。

20分鐘學會DBSCAN聚類演算法

2個演算法引數:鄰域半徑R和最少點數目minpoints。

這兩個演算法引數實際可以刻畫什麼叫密集——當鄰域半徑R內的點的個數大於最少點數目minpoints時,就是密集。

20分鐘學會DBSCAN聚類演算法

3種點的類別:核心點,邊界點和噪聲點。

鄰域半徑R內樣本點的數量大於等於minpoints的點叫做核心點。不屬於核心點但在某個核心點的鄰域內的點叫做邊界點。既不是核心點也不是邊界點的是噪聲點。

20分鐘學會DBSCAN聚類演算法

4種點的關係:密度直達,密度可達,密度相連,非密度相連。

如果P為核心點,Q在P的R鄰域內,那麼稱P到Q密度直達。任何核心點到其自身密度直達,密度直達不具有對稱性,如果P到Q密度直達,那麼Q到P不一定密度直達。

如果存在核心點P2,P3,……,Pn,且P1到P2密度直達,P2到P3密度直達,……,P(n-1)到Pn密度直達,Pn到Q密度直達,則P1到Q密度可達。密度可達也不具有對稱性。

如果存在核心點S,使得S到P和Q都密度可達,則P和Q密度相連。密度相連具有對稱性,如果P和Q密度相連,那麼Q和P也一定密度相連。密度相連的兩個點屬於同一個聚類簇。

如果兩個點不屬於密度相連關係,則兩個點非密度相連。非密度相連的兩個點屬於不同的聚類簇,或者其中存在噪聲點。

20分鐘學會DBSCAN聚類演算法

二,DBSCAN演算法步驟

DBSCAN的演算法步驟分成兩步。

1,尋找核心點形成臨時聚類簇。

掃描全部樣本點,如果某個樣本點R半徑範圍內點數目>=MinPoints,則將其納入核心點列表,並將其密度直達的點形成對應的臨時聚類簇。

2,合併臨時聚類簇得到聚類簇。

對於每一個臨時聚類簇,檢查其中的點是否為核心點,如果是,將該點對應的臨時聚類簇和當前臨時聚類簇合並,得到新的臨時聚類簇。

重複此操作,直到當前臨時聚類簇中的每一個點要麼不在核心點列表,要麼其密度直達的點都已經在該臨時聚類簇,該臨時聚類簇升級成為聚類簇。

繼續對剩餘的臨時聚類簇進行相同的合併操作,直到全部臨時聚類簇被處理。

20分鐘學會DBSCAN聚類演算法

三,DBSCAN使用範例

1,生成樣本點

程式碼語言:javascript
複製
import numpy as np
import pandas as pd
from sklearn import datasets
%matplotlib inline

X,_ = datasets.make_moons(500,noise = 0.1,random_state=1)
df = pd.DataFrame(X,columns = ['feature1','feature2'])

df.plot.scatter('feature1','feature2', s = 100,alpha = 0.6, title = 'dataset by make_moon')
20分鐘學會DBSCAN聚類演算法

2,呼叫dbscan介面完成聚類

程式碼語言:javascript
複製
from sklearn.cluster import dbscan

# eps為鄰域半徑,min_samples為最少點數目
core_samples,cluster_ids = dbscan(X, eps = 0.2, min_samples=20) 
# cluster_ids中-1表示對應的點為噪聲點

df = pd.DataFrame(np.c_[X,cluster_ids],columns = ['feature1','feature2','cluster_id'])
df['cluster_id'] = df['cluster_id'].astype('i2')

df.plot.scatter('feature1','feature2', s = 100,
    c = list(df['cluster_id']),cmap = 'rainbow',colorbar = False,
    alpha = 0.6,title = 'DBSCAN cluster result')
20分鐘學會DBSCAN聚類演算法

相關文章