DBscan算法及其Python實現


DBSCAN簡介:

1.簡介
  DBSCAN 算法是一種基於密度的空間聚類算法。該算法利用基於密度的聚類的概念,即要求聚類空間中的一定區域內所包含對象(點或其它空間對象)的數目不小於某一給定閥值。DBSCAN 算法的顯著優點是聚類速度快且能夠有效處理噪聲點和發現任意形狀的空間聚類。但是由於它直接對整個數據庫進行操作且進行聚類時使用了一個全局性的表征密度的參數,因此也具有兩個比較明顯的弱點:

        1. 當數據量增大時,要求較大的內存支持 I/0 消耗也很大;

        2. 當空間聚類的密度不均勻、聚類間距離相差很大時,聚類質量較差。


2.DBSCAN算法的聚類過程
  DBSCAN算法基於一個事實:一個聚類可以由其中的任何核心對象唯一確定。等價可以表述為: 任一滿足核心對象條件的數據對象p,數據庫D中所有從p密度可達的數據對象所組成的集合構成了一個完整的聚類C,且p屬於C。


3.DBSCAN中的幾個定義
  密度可達是直接密度可達的傳遞閉包,非對稱性關系;密度相連是對稱性關系。DBSCA目的是找到密度相連對象的最大集合。

  E領域:給定對象p半徑為E內的區域稱為該對象的E領域;

  核心對象:p的E領域內樣本數大於MinPts(算法輸入值),則該對象p為核心對象;

  直接密度可達:對於樣本集合D,如果樣本點q在p的E領域內,且p為核心對象,則p直接密度可達q;

  密度可達:對於樣本集合D,存在一串樣本點p1,p2,p3,...pn,其中連續兩個點直接密度可達,則 p=p1,q=qn,則p密度可達q;

  密度相連:對於樣本集合D中任意一點o,存在p到o密度可達,並且q到o密度可達,那么q從p密度相連;

 

from matplotlib.pyplot import *  
 from collections import defaultdict  
 import random  
   
 #function to calculate distance  
 def dist(p1, p2):  
   return ((p1[0]-p2[0])**2+ (p1[1]-p2[1])**2)**(0.5)  
   
 #randomly generate around 100 cartesian coordinates  
 all_points=[]  
   
 for i in range(100):  
   randCoord = [random.randint(1,50), random.randint(1,50)]  
   if not randCoord in all_points:  
     all_points.append(randCoord)  
   
   
 #take radius = 8 and min. points = 8  
 E = 8  
 minPts = 8  
   
 #find out the core points  
 other_points =[]  
 core_points=[]  
 plotted_points=[]  
 for point in all_points:  
   point.append(0) # assign initial level 0  
   total = 0  
   for otherPoint in all_points:  
     distance = dist(otherPoint,point)  
     if distance<=E:  
       total+=1  
   
   if total > minPts:  
     core_points.append(point)  
     plotted_points.append(point)  
   else:  
     other_points.append(point)  
   
 #find border points  
 border_points=[]  
 for core in core_points:  
   for other in other_points:  
     if dist(core,other)<=E:  
       border_points.append(other)  
       plotted_points.append(other)  
   
   
 #implement the algorithm  
 cluster_label=0  
   
 for point in core_points:  
   if point[2]==0:  
     cluster_label+=1  
     point[2]=cluster_label  
   
   for point2 in plotted_points:  
     distance = dist(point2,point)  
     if point2[2] ==0 and distance<=E:  
       print point, point2  
       point2[2] =point[2]  
   
   
 #after the points are asssigned correnponding labels, we group them  
 cluster_list = defaultdict(lambda: [[],[]])  
 for point in plotted_points:  
   cluster_list[point[2]][0].append(point[0])  
   cluster_list[point[2]][1].append(point[1])  
   
 markers = ['+','*','.','d','^','v','>','<','p']  
   
 #plotting the clusters  
 i=0  
 print cluster_list  
 for value in cluster_list:  
   cluster= cluster_list[value]  
   plot(cluster[0], cluster[1],markers[i])  
   i = i%10+1  
   
 #plot the noise points as well  
 noise_points=[]  
 for point in all_points:  
   if not point in core_points and not point in border_points:  
     noise_points.append(point)  
 noisex=[]  
 noisey=[]  
 for point in noise_points:  
   noisex.append(point[0])  
   noisey.append(point[1])  
 plot(noisex, noisey, "x")  
   
 title(str(len(cluster_list))+" clusters created with E ="+str(E)+" Min Points="+str(minPts)+" total points="+str(len(all_points))+" noise Points = "+ str(len(noise_points)))  
 axis((0,60,0,60))  
 show()

參考地址:http://www.cnblogs.com/sungyouyu/p/3636708.html#undefined


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM