Python机器学习——DBSCAN聚类
密度聚類(lèi)(Density-based Clustering)假設(shè)聚類(lèi)結(jié)構(gòu)能夠通過(guò)樣本分布的緊密程度來(lái)確定。DBSCAN是常用的密度聚類(lèi)算法,它通過(guò)一組鄰域參數(shù)(??,MinPtsMinPts)來(lái)描述樣本分布的緊密程度。給定數(shù)據(jù)集DD={x??1,x??2,x??3,...,x??Nx→1,x→2,x→3,...,x→N},數(shù)據(jù)集屬性定義如下。
-
??-鄰域:N?(x??i)N?(x→i)={x??j∈D|distance(x??i,x??j)x→j∈D|distance(x→i,x→j)≤?≤?},N?(x??i)N?(x→i)包含了樣本集DD中與x??ix→i距離不大于??的所有樣本。
-
核心對(duì)象core object:若|N?(x??i)N?(x→i)|≥MinPts≥MinPts,則稱(chēng)x??ix→i是一個(gè)核心對(duì)象。即:若x??ix→i的??-鄰域中至少包含MinPtsMinPts個(gè)樣本,則稱(chēng)x??ix→i是一個(gè)核心對(duì)象。
-
密度直達(dá)directly density-reachable:若x??ix→i是一個(gè)核心對(duì)象,且x??j∈x→j∈N?(x??i)N?(x→i),則稱(chēng)x??jx→j由x??ix→i密度直達(dá),記作x??ix→i–>x??jx→j。
-
密度可達(dá)density-reachable:對(duì)于x??ix→i和x??jx→j,若存在樣本序列(p??0,p??1,p??2,...,p??m,p??m+1p→0,p→1,p→2,...,p→m,p→m+1),其中p??0p→0=x??ix→i,p??m+1p→m+1=x??jx→j,p??s∈D,s=1,2,...,mp→s∈D,s=1,2,...,m。如果p??s+1p→s+1由p??s,s=1,2,...,mp→s,s=1,2,...,m密度直達(dá),則稱(chēng)x??jx→j由x??ix→i密度可達(dá),記作x??ix→i~>x??jx→j。
- 密度相連density-connected:對(duì)于x??ix→i和x??jx→j,若存在x??kx→k,使得x??ix→i和x??jx→j均由x??kx→k密度可達(dá),則稱(chēng)x??jx→j由x??ix→i密度相連,記作x??ix→i~x??jx→j。
??DBSCAN算法的定義:給定鄰域參數(shù)(??,MinPtsMinPts),一個(gè)簇C?DC?D是滿(mǎn)足下列性質(zhì)的非空樣本子集:
- 接性connectivity:若x??i∈C,x??j∈Cx→i∈C,x→j∈C,則x??ix→i~x??jx→j
- 大性maximality:若x??i∈Cx→i∈C,且→xi→xi~>x??jx→j,則x??j∈Cx→j∈C?
即一個(gè)簇是由密度可達(dá)關(guān)系導(dǎo)出的最大的密度相連樣本集合。
??DBSCAN算法的思想:若x??x→為核心對(duì)象,則x??x→密度可達(dá)的所有樣本組成的集合X={x???∈D|x??x→?∈D|x→~>x???x→?},可以證明XX就是滿(mǎn)足連接性與最大性的簇。于是DBSCAN算法首選任選數(shù)據(jù)集中的一個(gè)核心對(duì)象作為種子seedseed,再由此出發(fā)確定相應(yīng)的聚類(lèi)簇。
下面給出DBSCAN算法:
-
輸入
- 數(shù)據(jù)集DD={x??1,x??2,x??3,...,x??Nx→1,x→2,x→3,...,x→N}
- 鄰域參數(shù)(??,MinPtsMinPts)
-
輸出:簇劃分CC={C1,C2,...,CkC1,C2,...,Ck}
- 算法步驟如下:?
- 初始化核心對(duì)象集合為空集:Ω=??
- 尋找核心對(duì)象:遍歷所有的樣本點(diǎn)x??i,i=1,2,...,Nx→i,i=1,2,...,N,計(jì)算N?(x??i)N?(x→i),如果|N?(x??i)N?(x→i)|≥MinPts≥MinPts,則Ω=Ω??{x??ix→i}
- 迭代:以任一未訪問(wèn)過(guò)的核心對(duì)象為出發(fā)點(diǎn),找出有其密度可達(dá)的樣本生成的聚類(lèi)簇,直到所有的核心對(duì)象都被訪問(wèn)為止
?
Python 實(shí)戰(zhàn)
?
??DBSCANDBSCAN是sciki?kearnsciki?kearn提供的密度聚類(lèi)算法模型,其原型為:
class sklearn.cluster.DBSCAN(eps=0.5,min_samples=5,metric='euclidean',algorithm='auto',leaf_size=30,p=None,random_state=None) - 1
參數(shù)
- epseps:??參數(shù),用于確定鄰域大小。
- min_samplesmin_samples:MinPtsMinPts參數(shù),用于判斷核心對(duì)象。
- metricmetric:一個(gè)字符串或可調(diào)用對(duì)象,用于計(jì)算距離。如果是字符串,則必須是在metrics.pairwise.calculate_distance中指定。
- algorithmalgorithm:一個(gè)字符串,用于計(jì)算兩點(diǎn)間距離并找出最近鄰的點(diǎn),可以為如下:?
- ‘a(chǎn)utoauto’:由算法自動(dòng)取舍合適的算法。
- ‘ball_treeball_tree’:用ball樹(shù)來(lái)搜索。
- ‘kd_treekd_tree’:用kd樹(shù)搜索。
- ‘brutebrute’:暴力搜索。
- leaf_sizeleaf_size:一個(gè)整數(shù),用于指定當(dāng)algorithm=ball_tree或kd_tree時(shí),樹(shù)的葉節(jié)點(diǎn)大小。該參數(shù)會(huì)影響構(gòu)建樹(shù),搜索最近鄰的速度,同時(shí)影響樹(shù)的內(nèi)存。
- random_staterandom_state:被廢棄的接口,將在scikit-learn v 0.18中移除。
屬性
- core_sample_indices_core_sample_indices_:核心樣本在原始訓(xùn)練集中的位置。
- components_components_:核心樣本的一份副本。
- labels_labels_:每個(gè)樣本所屬的簇標(biāo)記。對(duì)于噪聲樣本,其簇標(biāo)記為-1副本。
方法
- fit(X[,y,sample_weight])fit(X[,y,sample_weight]):訓(xùn)練模型。
- fit_predict(X[,y,sample_weight])fit_predict(X[,y,sample_weight]):訓(xùn)練模型并預(yù)測(cè)每個(gè)樣本所屬的簇標(biāo)記。
#導(dǎo)包
from sklearn import cluster
from sklearn.metrics import adjusted_rand_score
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets.samples_generator import make_blobs
from sklearn import mixture
from sklearn.svm.libsvm import predict - 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
#產(chǎn)生數(shù)據(jù)
def create_data(centers,num=100,std=0.7):X,labels_true = make_blobs(n_samples=num,centers=centers, cluster_std=std)return X,labels_true - 1
- 2
- 3
- 4
"""數(shù)據(jù)作圖
"""
def plot_data(*data):X,labels_true=datalabels=np.unique(labels_true)fig=plt.figure()ax=fig.add_subplot(1,1,1)colors='rgbycm'for i,label in enumerate(labels):position=labels_true==labelax.scatter(X[position,0],X[position,1],label="cluster %d"%label),color=colors[i%len(colors)]ax.legend(loc="best",framealpha=0.5)ax.set_xlabel("X[0]")ax.set_ylabel("Y[1]")ax.set_title("data")plt.show() - 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
#測(cè)試函數(shù)
def test_DBSCAN(*data):X,labels_true = dataclst = cluster.DBSCAN();predict_labels = clst.fit_predict(X)print("ARI:%s"%adjusted_rand_score(labels_true,predict_labels))print("Core sample num:%d"%len(clst.core_sample_indices_)) - 1
- 2
- 3
- 4
- 5
- 6
- 7
#結(jié)果
ARI:0.330307120902
Core sample num:991 - 1
- 2
- 3
??其中ARIARI指標(biāo)為0.330307120902,該值越大越好,DBSCAN根據(jù)密度,將原始數(shù)據(jù)集劃分為991個(gè)簇。
下面考察??參數(shù)的影響:
def test_DBSCAN_epsilon(*data):X,labels_true = dataepsilons = np.logspace(-1,1.5)ARIs=[]Core_nums = []for epsilon in epsilons:clst = cluster.DBSCAN(eps=epsilon)predicted_labels = clst.fit_predict(X)ARIs.append(adjusted_rand_score(labels_true,predicted_labels))Core_nums.append(len(clst.core_sample_indices_))fig = plt.figure(figsize=(10,5))ax = fig.add_subplot(1,2,1)ax.plot(epsilons,ARIs,marker = '+')ax.set_xscale('log')ax.set_xlabel(r"$\epsilon$")ax.set_ylim(0,1)ax.set_ylabel('ARI')ax = fig.add_subplot(1,2,2)ax.plot(epsilons,Core_nums,marker='o')ax.set_xscale('log')ax.set_xlabel(r"$\epsilon$")ax.set_ylabel('Core_num')fig.suptitle("DBSCAN")plt.show() - 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
centers = [[1,1],[1,2],[2,2],[10,20]]
X,labels_true = create_data(centers,1000,0.5)
test_DBSCAN_epsilon(X,labels_true) - 1
- 2
- 3
??參數(shù)的影響結(jié)果如上圖所示:
??可以看到ARIARI指數(shù)隨著??的增長(zhǎng),先上升后保持平穩(wěn),最后懸崖式下降。懸崖式下降是因?yàn)槲覀儺a(chǎn)生的訓(xùn)練樣本的間距比較小,最遠(yuǎn)的兩個(gè)樣本之間的距離不超過(guò)30,當(dāng)??過(guò)大時(shí),所有的點(diǎn)都在一個(gè)鄰域中。?
??樣本核心數(shù)量隨著??的增長(zhǎng)而上升,這是因?yàn)殡S著??的增長(zhǎng),樣本點(diǎn)的鄰域在擴(kuò)展,則樣本點(diǎn)鄰域中的樣本會(huì)增多,這就產(chǎn)生了更多滿(mǎn)足條件的核心樣本點(diǎn)。但是樣本集中的樣本數(shù)量有限,因此核心樣本點(diǎn)的數(shù)量增長(zhǎng)到一定數(shù)目后會(huì)趨于穩(wěn)定。
下面接著考察MinPtsMinPts參數(shù)的影響:
def test_DBSCAN_min_samples(*data):X,labels_true=datamin_samples=range(1,100)ARIs=[]Core_nums=[]for num in min_samples:clst=cluster.DBSCAN(min_samples=num)predicted_labels=clst.fit_predict(X)ARIs.append(adjusted_rand_score(labels_true, predicted_labels))Core_nums.append(len(clst.core_sample_indices_))fig=plt.figure(figsize=(10,5))ax=fig.add_subplot(1,2,1)ax.plot(min_samples,ARIs,marker='+')ax.set_xlabel("min_samples")ax.set_ylim(0,1)ax.set_ylabel('ARI')ax=fig.add_subplot(1,2,2)ax.plot(min_samples,Core_nums,marker='o')ax.set_xlabel("min_samples")ax.set_ylabel('Core_nums')fig.suptitle("DBSCAN")plt.show() - 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
centers = [[1,1],[1,2],[2,2],[10,20]]
X,labels_true = create_data(centers,1000,0.5)
test_DBSCAN_min_samples(X,labels_true) - 1
- 2
- 3
MinPtsMinPts參數(shù)的影響結(jié)果如下:
??可以看出ARIARI指數(shù)隨著MinPtsMinPts的增長(zhǎng),平穩(wěn)地下降。而核心樣本數(shù)量隨著MinPtsMinPts的增長(zhǎng)基本呈線(xiàn)性下降,這是因?yàn)殡S著MinPtsMinPts的增長(zhǎng),樣本點(diǎn)的鄰域中必須包含更多的樣本才能使它成為一個(gè)核心點(diǎn)。因此產(chǎn)生的樣本點(diǎn)數(shù)量越來(lái)越少。
有關(guān)ARIARI,請(qǐng)參考:
總結(jié)
以上是生活随笔為你收集整理的Python机器学习——DBSCAN聚类的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 聚类和EM算法——K均值聚类
- 下一篇: Python机器学习——Agglomer