1、前言python
2、DBSCAN聚類算法算法
3、參數選擇數據庫
4、DBSCAN算法迭代可視化展現函數
5、經常使用的評估方法:輪廓係數網站
6、用Python實現DBSCAN聚類算法spa
去年學聚類算法的R語言的時候,有層次聚類、系統聚類、K-means聚類、K中心聚類,最後呢,被DBSCAN聚類算法迷上了,爲何呢,首先它能夠發現任何形狀的簇,其次我認爲它的理論也是比較簡單易懂的。今年在python這門語言上我打算好好弄弄DBSCAN。下面貼上它的官方解釋:.net
DBSCAN(Density-Based Spatial Clustering of Applications with Noise,具備噪聲的基於密度的聚類方法)是一種基於密度的空間聚類算法。 該算法將具備足夠密度的區域劃分爲簇,並在具備噪聲的空間數據庫中發現任意形狀的簇,它將簇定義爲密度相連的點的最大集合。3d
文字看不懂看下面這個圖。下面這些點是分佈在樣本空間的衆多樣本,如今咱們的目標是把這些在樣本空間中距離相近的聚成一類。咱們發現A點附近的點密度較大,紅色的圓圈根據必定的規則在這裏滾啊滾,最終收納了A附近的5個點,標記爲紅色也就是定爲同一個簇。其它沒有被收納的根據同樣的規則成簇。(形象來講,咱們能夠認爲這是系統在衆多樣本點中隨機選中一個,圍繞這個被選中的樣本點畫一個圓,規定這個圓的半徑以及圓內最少包含的樣本點,若是在指定半徑內有足夠多的樣本點在內,那麼這個圓圈的圓心就轉移到這個內部樣本點,繼續去圈附近其它的樣本點,相似傳銷同樣,繼續去發展下線。等到這個滾來滾去的圈發現所圈住的樣本點數量少於預先指定的值,就中止了。那麼咱們稱最開始那個點爲核心點,如A,停下來的那個點爲邊界點,如B、C,沒得滾的那個點爲離羣點,如N)。code
基於密度這點有什麼好處呢,咱們知道kmeans聚類算法只能處理球形的簇,也就是一個聚成實心的團(這是由於算法自己計算平均距離的侷限)。但每每現實中還會有各類形狀,好比下面兩張圖,環形和不規則形,這個時候,那些傳統的聚類算法顯然就悲劇了。因而就思考,樣本密度大的成一類唄。吶這就是DBSCAN聚類算法。blog
上面提到了紅色圓圈滾啊滾的過程,這個過程就包括了DBSCAN算法的兩個參數,這兩個參數比較難指定,公認的指定方法簡單說一下:
以上雖然是一個可取的方式,可是有時候比較麻煩 ,大部分仍是都試一試進行觀察,用k距離須要作大量實驗來觀察,很難一次性把這些值都選準。
國外有一個特別有意思的網站:https://www.naftaliharris.com/blog/visualizing-dbscan-clustering/
它能夠把咱們DBSCAN的迭代過程動態圖畫出來
設置好參數,點擊GO! 就開始聚類了!
直接跳到最後看一下DBSCAN的聚類結果,以下:
若是minPoints參數設置再大一點,那麼這個笑臉可能會更好看。沒有顏色標註的就是圈不到的樣本點,也就是離羣點,DBSCAN聚類算法在檢測離羣點的任務上也有較好的效果。若是是傳統的Kmeans聚類,咱們也來看一下效果:
是否是好醜,這完美的體現出來DBSCAN算法基於密度聚類的優點了啊.
這裏提一下聚類算法中最經常使用的評估方法——輪廓係數(Silhouette Coefficient):
ji
import pandas as pd # 導入數據 beer = pd.read_csv('data.txt', sep=' ') print(beer)
輸出結果:
from sklearn.cluster import DBSCAN X = beer[["calories","sodium","alcohol","cost"]] # 設置半徑爲10,最小樣本量爲2,建模 db = DBSCAN(eps=10, min_samples=2).fit(X) labels = db.labels_ beer['cluster_db'] = labels # 在數據集最後一列加上通過DBSCAN聚類後的結果 beer.sort_values('cluster_db') # 注:cluster列是kmeans聚成3類的結果;cluster2列是kmeans聚類成2類的結果;scaled_cluster列是kmeans聚類成3類的結果(通過了數據標準化)
輸出結果:
# 查看根據DBSCAN聚類後的分組統計結果(均值) print(beer.groupby('cluster_db').mean())
# 畫出在不一樣兩個指標下樣本的分佈狀況 print(pd.scatter_matrix(X, c=colors[beer.cluster_db], figsize=(10,10), s=100))
# 咱們能夠從上面這個圖裏觀察聚類效果的好壞,可是當數據量很大,或者指標不少的時候,觀察起來就會很是麻煩。 from sklearn import metrics # 就是下面這個函數能夠計算輪廓係數(sklearn真是一個強大的包) score = metrics.silhouette_score(X,beer.cluster_db) print(score)