dbscan算法_DBSCAN聚类算法探索
作者:單華
DBSCAN是非監督學習中密度學習算法里的佼佼者。本文對DBSCAN做了簡單的探索,全文無數學公式,共2800余字。
在ARGO之前提到的聚類與K-Means一文中,提到了密度聚類方法DBSCAN算法。那么本文將對這一聚類方法進行詳細介紹,具體包括:
- DBSCAN定義及基本概念
- 算法原理和算法流程
- 算法的優缺點
- 用Scikit-learn學習DBSCAN聚類算法
一 DBSCAN定義及基本概念
DBSCAN(Density-Based SpatialClustering of Applications with Noise)是一種典型的密度聚類算法,這種聚類算法將簇視為由低密度區域隔離開來的高密度區域。由于這種相當普遍的觀點,DBSCAN能在有噪音的空間數據中發現任意形狀、大小分布的簇。
DBSCAN是基于一組鄰域來描述樣本集緊密程度的,它有兩個輸入參數:鄰域半徑Eps 和 密度閾值 MinPts。通過這兩個參數可以區分出高密度點和低密度點,簡單地說,就是某個數據點的鄰域半徑范圍Eps內的數據點數目超過了最小包含點數閾值MinPts 即為高密度點,而DBSCAN 的主要思想就是將滿足高密度的數據點聚類成一個簇。
對應樣本集D, DBSCAN 算法包含基本概念如下:
- Eps鄰域:對于給定對象q(q ∈ D),q的Eps鄰域是以q為中心,Eps半徑內的鄰域。
- 核心對象:對于給定對象q(q ∈ D),如果q的Eps鄰域至少包含最小數目MinPts的對象,則稱q為核心對象。
- 邊界對象:對于給定對象q(q ∈ D),如果q在某個核心對象的鄰域內,但又不是核心對象,則稱q為邊界對象。
- 噪音點:既不是核心點,也不是邊界點的任何點。
- 直接密度可達:如果q在r的Eps鄰域內,而r是一個核心對象,則稱q從r直接密度可達。
- 密度可達:存在對象鏈 , 。若所有的對象 從對象 關于Eps 和MinPts 直接密度可達,則稱q 從p 關于Eps 和MinPts 密度可達。
- 密度相連:給定對象r, p,q ∈D,若 p 和 q 都是從 r 出發,關于 Eps和MinPts 密度可達的,則稱p 和q 是關于Eps 和MinPts 密度連接的。
從下圖可以很容易理解上述概念,圖中MinPts=5,紅色的點是核心對象,因為其Eps-鄰域至少有5個樣本。黑色的點是非核心對象。所有核心對象直接密度可達的樣本在以紅色核心對象為中心的超球體內,如果不在超球體內,則不能直接密度可達。圖中用綠色箭頭連起來的核心對象組成了密度可達的樣本序列。在這些密度可達的樣本序列的Eps-鄰域內所有的樣本相互都是密度相連的。而那些不在任何超求體內的黑點則成為噪聲。
二 算法原理和算法流程
DBSCAN算法的基本思路很簡單:它從數據對象集合D 中任意沒有類別的對象q開始,尋找從q 關于參數Eps 和MinPts 密度可達的所有對象,組成一個聚類。DBSCAN的聚類過程也叫密度擴展,整個過程由迭代的鄰域搜索來完成。“具體做法是從某一核心點出發,不斷的向密度可達的區域擴張,得到一個包含核心點和邊界點的最大區域,這個區域中任意兩點密度相連”。
根據上述分析,我們可以將DBSCAN 算法描述如下:
輸入:包含n 個對象的數據集D,鄰域半徑Eps,密度閾值MinPts。期待輸出:所有生成的簇。
1 初始化參數:設置數據庫中所有對象為噪聲和未訪問。
2 從數據庫中任選一個未被訪問的核心對象,以該對象作為起始對象建立一個新類,遞歸地找出所有從該對象密度可達的對象,加入到該類中,并標記為已訪問;
3 直到所有的對象都被訪問,輸出聚類結果,算法結束;否則轉2步。
用流程圖描述如下:
三 算法的優缺點
DBSCAN算法是基于密度聚類的代表,針對前面的算法描述,我們對DBSCAN算法的優缺點做一個總結。
DBSCAN具有以下主要優點:
1) 對噪聲數據不敏感,可以發現空間中任意形狀和大小的簇;
2) 由于只掃描一次整個數據庫,算法是高效的;
3) 與K-means比起來,不需要輸入類別的個數;
4) 聚類結果幾乎不依賴于點遍歷順序。
但DBSCAN也存在如下一些缺點:
1) 高內存和I/O消耗:隨著輸入數據集規模的增大,由于算法將整個數據集加載到內存,對內存和I/O消耗較高;
2) 對輸入參數Eps敏感:鄰域半徑Eps 是由用戶在進行聚類前指定的,但實際上,在沒有關于數據集的領域知識的指導下,很難確定合適的參數。然而聚類結果卻與該參數有著很大關系:如果Eps過大,就可能將距離較遠的幾個簇合并起來,或者將噪聲數據添加到簇中;如果過小,就可能把一個簇分割成幾個更小的簇,或者將有用的數據識別為噪聲。
為了輔助參數Eps 的確定,DBSCAN 算法提供了一種可視化的方法:給定k值,計算數據庫中每個對象與其第k 最近鄰居之間的距離kdist,并對kdist 值由大到小排序,隨后以對象在排序后的kdist 序列中的序號作為橫坐標,對應的kdist值(圖中為4dist)作為縱坐標,繪制出二維kdist 曲線圖。用戶將kdist曲線由陡峭轉為平緩的拐點處的kdist 值設置為參數Eps。在實際操作中,通過這種交互式方法確定的Eps 具有一定的合理性,但需要過多的人工參與。
3) 不能有效地對密度差異較大的數據集進行聚類:如果樣本集的密度不均勻、聚類間距差相差很大時,聚類質量較差,這時用DBSCAN聚類一般不適合。
四 用Scikit-learn學習DBSCAN聚類算法
在scikit-learn中,我們直接使用sklearn-cluster.DBSCAN調用封裝好的DBSCAN聚類函數。
我們隨機生成一組數據樣本點,其中兩組數據是非凸的,一組為凸的。代碼如下所示:
import numpy as np import matplotlib.pyplot as plt from sklearn import datasetsX1, y1=datasets.make_circles(n_samples=1000, factor=.7,noise=.035) X2, y2 = datasets.make_blobs(n_samples=500, n_features=2, centers=[[1.5,1.5]], cluster_std=[[.075]],random_state=9)X = np.concatenate((X1, X2)) plt.scatter(X[:, 0], X[:, 1], marker='o') plt.show()其點分布如下:
使用K-Means聚類
看一下K-means算法的分類效果,假設分為三類,代碼如下:
from sklearn.cluster import KMeans y_pred = KMeans(n_clusters=3, random_state=9).fit_predict(X) plt.scatter(X[:, 0], X[:, 1], c=y_pred) plt.show()下面的K-means聚類效果圖很明顯,并不是我們想要的聚類結果。
使用DBCAN進行聚類
DBSCAN的初始函數的參數,初始化函數如下
_int_(eps=0.5, min_samples=5, metric='euclidean', algorithm='auto', leaf_size=30, p=None, n_jobs=1)[eps] DBSCAN算法參數,兩個樣本被看作鄰居的最大距離,即掃描半徑,默認值是0.5。但是eps如果選擇過大,則會有很多的樣本點落入核心對象的鄰域內,這時就會導致劃分的類別減少;而如果eps選擇過小,就會導致劃分的類別增多,本來是一類的樣本可能就會被分開。
[min_samples] 即前面提到的MinPts參數,作為核心對象鄰域中的最小樣本數,默認值是5。通常和eps一起調參。而且在eps值一定的情況下,min_sample偏大,則核心對象會減少,這時本來是一類的樣本可能會被標記為噪音點,類別也會變多。反之min_sample偏小的話,核心對象就會增多,導致劃分的類別減少。
[algorithm]最近鄰搜索算法參數,有四種“auto,ball_tree,kd_tree,brute”,一般使用默認的“auto”就夠了,它會從其他三個算法中做權衡,選擇一個擬合最好的最優算法。但是如果輸入樣本是稀疏的,則會自動選擇“brute”算法搜索。
[metric,leaf_size,p,n_jobs]對于這幾個參數,可以參考前面KNN算法一文中的詳細介紹,這里不再做說明。
上述介紹了DBSCAN函數的參數后,我們開始對輸入的參數進行調整。從默認函數的分類效果可以發現,劃分的類別比我們期望的少,那么可以通過增大min_samples,減小eps半徑來達到我們的目的:
from sklearn.cluster import DBSCAN y_pred = DBSCAN(eps=0.1,min_samples = 10).fit_predict(X) plt.scatter(X[:, 0], X[:, 1], c=y_pred) plt.show()那么我們再來看看這時的聚類效果圖如何吧:
明顯的,與我們期望的劃分結果完全符合。
總結
本文從DBSCAN算法的基本原理講起,中間介紹了DBSCAN的算法流程,并在末節用實戰展示了DBSCAN和KMeans的區別和使用。DBSCAN在特征工程中對于發現噪音點也有使用場景,是使用比較廣泛的一種聚類方式。
原文鏈接
DBSCAN聚類算法探索?mp.weixin.qq.com總結
以上是生活随笔為你收集整理的dbscan算法_DBSCAN聚类算法探索的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python网络通信编程实例_pytho
- 下一篇: c判断char数组是否为空_你学过数组,