集成學(xué)習(xí)聚類算法DBSCAN密度聚類算法詳解和可視化調(diào)參

DBSCAN(Density-Based Spatial Clustering of Applications with Noise,具有噪聲的基于密度的聚類方法)是一種很典型的密度聚類算法,和只適用于凸樣本集的K-Means聚類相比,DBSCAN既可以適用于凸樣本集,也可以適用于非凸樣本集。
DBSCAN一般假定類別可以通過樣本分布的緊密程度決定。同一類別的樣本,他們之間的緊密相連的,也就是說,在該類別任意樣本周圍不遠(yuǎn)處一定有同類別的樣本存在。通過將緊密相連的樣本劃為一類,這樣就得到了一個(gè)聚類類別。通過將所有各組緊密相連的樣本劃為各個(gè)不同的類別,則我們就得到了最終的所有聚類類別結(jié)果。

紅色的點(diǎn)都是核心對(duì)象,黑色的樣本是非核心對(duì)象。所有核心對(duì)象密度直達(dá)的樣本在以紅色核心對(duì)象為中心的超球體內(nèi),如果不在超球體內(nèi),則不能密度直達(dá)。圖中用綠色箭頭連起來的核心對(duì)象組成了密度可達(dá)的樣本序列。

1、特點(diǎn)

和傳統(tǒng)的K-Means算法相比,DBSCAN最大的不同就是不需要輸入類別數(shù)k,當(dāng)然它最大的優(yōu)勢(shì)是可以發(fā)現(xiàn)任意形狀的聚類簇,而不是像K-Means,一般僅僅使用于凸的樣本集聚類。同時(shí)它在聚類的同時(shí)還可以找出異常點(diǎn),這點(diǎn)和BIRCH算法類似。
那么我們什么時(shí)候需要用DBSCAN來聚類呢?一般來說,如果數(shù)據(jù)集是稠密的,并且數(shù)據(jù)集不是凸的,那么用DBSCAN會(huì)比K-Means聚類效果好很多。如果數(shù)據(jù)集不是稠密的,則不推薦用DBSCAN來聚類。

2、Python實(shí)現(xiàn)

2.1 引入相關(guān)的模塊

import numpy as np
from sklearn.cluster import DBSCAN
from sklearn import metrics
import seaborn as sns
import pandas as pd
from sklearn.datasets.samples_generator import make_blobs
from sklearn.preprocessing import StandardScaler

2.2查看樣本的分布

我們對(duì)data的分布用seaborn進(jìn)行查看。

data=[
 [-2.68420713,1.469732895],[-2.71539062,-0.763005825],[-2.88981954,-0.618055245],[-2.7464372,-1.40005944],[-2.72859298,1.50266052],
 [-2.27989736,3.365022195],[-2.82089068,-0.369470295],[-2.62648199,0.766824075],[-2.88795857,-2.568591135],[-2.67384469,-0.48011265],
 [-2.50652679,2.933707545],[-2.61314272,0.096842835],[-2.78743398,-1.024830855],[-3.22520045,-2.264759595],[-2.64354322,5.33787705],
 [-2.38386932,6.05139453],[-2.6225262,3.681403515],[-2.64832273,1.436115015],[-2.19907796,3.956598405],[-2.58734619,2.34213138],
 [1.28479459,3.084476355],[0.93241075,1.436391405],[1.46406132,2.268854235],[0.18096721,-3.71521773],[1.08713449,0.339256755],
 [0.64043675,-1.87795566],[1.09522371,1.277510445],[-0.75146714,-4.504983795],[1.04329778,1.030306095],[-0.01019007,-3.242586915],
 [-0.5110862,-5.681213775],[0.51109806,-0.460278495],[0.26233576,-2.46551985],[0.98404455,-0.55962189],[-0.174864,-1.133170065],
 [0.92757294,2.107062945],[0.65959279,-1.583893305],[0.23454059,-1.493648235],[0.94236171,-2.43820017],[0.0432464,-2.616702525],
 [4.53172698,-0.05329008],[3.41407223,-2.58716277],[4.61648461,1.538708805],[3.97081495,-0.815065605],[4.34975798,-0.188471475],
 [5.39687992,2.462256225],[2.51938325,-5.361082605],[4.9320051,1.585696545],[4.31967279,-1.104966765],[4.91813423,3.511712835],
 [3.66193495,1.0891728],[3.80234045,-0.972695745],[4.16537886,0.96876126],[3.34459422,-3.493869435],[3.5852673,-2.426881725],
 [3.90474358,0.534685455],[3.94924878,0.18328617],[5.48876538,5.27195043],[5.79468686,1.139695065],[3.29832982,-3.42456273]
]
data = pd.DataFrame(data)
data.columns=['x','y']

sns.relplot(x="x",y="y",data=data)

可以看出來,樣本數(shù)據(jù)可以分為三類。

接下來我通過DBSCAN算法如何把這三個(gè)分類找出來。

2.3 建立一個(gè)簡單的模型

db = DBSCAN(eps=1, min_samples=5).fit(data) #DBSCAN聚類方法 還有參數(shù),matric = ""距離計(jì)算方法
data['labels'] = db.labels_ #和X同一個(gè)維度,labels對(duì)應(yīng)索引序號(hào)的值 為她所在簇的序號(hào)。若簇編號(hào)為-1,表示為噪聲,我們把標(biāo)簽放回到data數(shù)據(jù)集中方便畫圖
labels = db.labels_
raito = data.loc[data['labels']==-1].x.count()/data.x.count() #labels=-1的個(gè)數(shù)除以總數(shù),計(jì)算噪聲點(diǎn)個(gè)數(shù)占總數(shù)的比例
print('噪聲比:', format(raito, '.2%'))
n_clusters_ = len(set(labels)) - (1 if -1 in labels else 0) # 獲取分簇的數(shù)目
print('分簇的數(shù)目: %d' % n_clusters_)
print("輪廓系數(shù): %0.3f" % metrics.silhouette_score(data, labels)) #輪廓系數(shù)評(píng)價(jià)聚類的好壞
sns.relplot(x="x",y="y", hue="labels",data=data)

噪聲比: 28.33%
分簇的數(shù)目: 4
輪廓系數(shù): 0.332

其中-1的點(diǎn)表示異常點(diǎn),即噪聲??梢钥闯鰜碛?7個(gè)點(diǎn)是噪聲,所以噪聲比就是17/60=28.33%,自動(dòng)分為4個(gè)類別。
這個(gè)分類和我們的實(shí)際還是有一點(diǎn)的差距的。接下來我們調(diào)整參數(shù),看看效果會(huì)不會(huì)好一點(diǎn)。

2.4 調(diào)參

我們嘗試對(duì)eps和min_samples的各自參數(shù)組合進(jìn)行擬合計(jì)算。

rs= []#存放各個(gè)參數(shù)的組合計(jì)算出來的模型評(píng)估得分和噪聲比
eps = np.arange(0.2,4,0.2) #eps參數(shù)從0.2開始到4,每隔0.2進(jìn)行一次
min_samples=np.arange(2,20,1)#min_samples參數(shù)從2開始到20

best_score=0
best_score_eps=0
best_score_min_samples=0

for i in eps:
 for j in min_samples:
 try:#因?yàn)椴煌膮?shù)組合,有可能導(dǎo)致計(jì)算得分出錯(cuò),所以用try
            db = DBSCAN(eps=i, min_samples=j).fit(data)
            labels= db.labels_#得到DBSCAN預(yù)測(cè)的分類便簽
            k=metrics.silhouette_score(data,labels) #輪廓系數(shù)評(píng)價(jià)聚類的好壞,值越大越好
            raito = len(labels[labels[:] == -1]) / len(labels) #計(jì)算噪聲點(diǎn)個(gè)數(shù)占總數(shù)的比例
            n_clusters_ = len(set(labels)) - (1 if -1 in labels else 0) # 獲取分簇的數(shù)目
            rs.append([i,j,k,raito,n_clusters_])
 if k>best_score:
                best_score=k
                best_score_eps=i
                best_score_min_samples=j

 except:
            db='' #這里用try就是遍歷i,j 計(jì)算輪廓系數(shù)會(huì)出錯(cuò)的,出錯(cuò)的就跳過
 else:
            db=''
rs= pd.DataFrame(rs)
rs.columns=['eps','min_samples','score','raito','n_clusters']
sns.relplot(x="eps",y="min_samples", size='score',data=rs)
sns.relplot(x="eps",y="min_samples", size='raito',data=rs)

不同的參數(shù)組合的得分情況,得分用的是輪廓系數(shù),此系數(shù)評(píng)價(jià)聚類的好壞,值越大越好,值越大,圖中的點(diǎn)就越大。

我們也可以看看噪聲比,噪聲比越小越好。

通過上圖可以看出來,同時(shí)參考得分越大越好,噪聲比越小越好,eps取值在1-2.5之間,min_samples取值在3-15之間,并且min_samples的影響不大。有很多的參數(shù)組合的結(jié)果的差不多,我們?cè)诤线m的組合中隨便選擇一組。
修改參數(shù)eps=1.3 min_samples=3,運(yùn)行下列代碼:

db = DBSCAN(eps=1.5, min_samples=3).fit(data) #DBSCAN聚類方法 還有參數(shù),matric = ""距離計(jì)算方法
data['labels'] = db.labels_ #和X同一個(gè)維度,labels對(duì)應(yīng)索引序號(hào)的值 為她所在簇的序號(hào)。若簇編號(hào)為-1,表示為噪聲,我們把標(biāo)簽放回到data數(shù)據(jù)集中方便畫圖
labels = db.labels_
raito = data.loc[data['labels']==-1].x.count()/data.x.count() #labels=-1的個(gè)數(shù)除以總數(shù),計(jì)算噪聲點(diǎn)個(gè)數(shù)占總數(shù)的比例
print('噪聲比:', format(raito, '.2%'))
n_clusters_ = len(set(labels)) - (1 if -1 in labels else 0) # 獲取分簇的數(shù)目
print('分簇的數(shù)目: %d' % n_clusters_)
print("輪廓系數(shù): %0.3f" % metrics.silhouette_score(data, labels)) #輪廓系數(shù)評(píng)價(jià)聚類的好壞
sns.relplot(x="x",y="y", hue="labels",data=data)

噪聲比: 8.33%
分簇的數(shù)目: 3
輪廓系數(shù): 0.376

image

比較好的自動(dòng)分為3類了。

3、DBSCAN算法的優(yōu)缺點(diǎn)

3.1 DBSCAN的主要優(yōu)點(diǎn)有:

  1. 可以對(duì)任意形狀的稠密數(shù)據(jù)集進(jìn)行聚類,相對(duì)的,K-Means之類的聚類算法一般只適用于凸數(shù)據(jù)集。
  2. 可以在聚類的同時(shí)發(fā)現(xiàn)異常點(diǎn),對(duì)數(shù)據(jù)集中的異常點(diǎn)不敏感。
  3. 聚類結(jié)果沒有偏倚,相對(duì)的,K-Means之類的聚類算法初始值對(duì)聚類結(jié)果有很大影響。

3.2 DBSCAN的主要缺點(diǎn)有:

  1. 如果樣本集的密度不均勻、聚類間距差相差很大時(shí),聚類質(zhì)量較差,這時(shí)用DBSCAN聚類一般不適合。
  2. 如果樣本集較大時(shí),聚類收斂時(shí)間較長,此時(shí)可以對(duì)搜索最近鄰時(shí)建立的KD樹或者球樹進(jìn)行規(guī)模限制來改進(jìn)。
  3. 調(diào)參相對(duì)于傳統(tǒng)的K-Means之類的聚類算法稍復(fù)雜,主要需要對(duì)距離閾值?,鄰域樣本數(shù)閾值MinPts聯(lián)合調(diào)參,不同的參數(shù)組合對(duì)最后的聚類效果有較大影響。
?著作權(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),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 本篇結(jié)構(gòu) 簡介 聚類算法的分類 K-Means聚類算法 DBSCAN聚類算法 本篇介紹了聚類算法的種類,重點(diǎn)關(guān)注K...
    w1992wishes閱讀 7,700評(píng)論 0 14
  • 一、算法描述 DBSCAN(Density-Based Spatial Clustering of Applic...
    owolf閱讀 19,855評(píng)論 2 8
  • 聚類算法 前面介紹的集中算法都是屬于有監(jiān)督機(jī)器學(xué)習(xí)方法,這章和前面不同,介紹無監(jiān)督學(xué)習(xí)算法,也就是聚類算法。在無監(jiān)...
    飄涯閱讀 41,753評(píng)論 3 51
  • 電影里,公主那么美。 鮮花盛開的草地上,回眸一笑,我見猶憐。
    最憐天上月q閱讀 290評(píng)論 0 1
  • 這兩天橙橙沒來上班,辦公室里聽不到她的笑聲,變得死氣沉沉的,于是我忍不住給橙橙發(fā)了微信:橙橙 ,姐想你...
    撐舟遠(yuǎn)航閱讀 355評(píng)論 0 1

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