1. 程式人生 > >DBSCAN演算法實現---Python

DBSCAN演算法實現---Python

生活不易啊,公司考核,初步寫出來了,腦闊疼。。。

思路:

  設定閾值與半徑;

  計算點之間的距離(歐式距離實現);

  區分核心點、邊界點與離群點;

  將每個點的領域作為一個類(即將密度可達的點歸為一個簇);

  找出每個獨立的領域;

  對最後的聚類進行標記;

  視覺化。

 

程式碼實現:

  1、設定eps = 2,MinPts  = 3;

  2、實現點與點歐氏距離的計算

 1 def ecludDist(x,y):
 2     return np.sqrt(sum(np.sqrt(np.array(x) - np.array(y))))
3 4 def euclidean_distance(data): 5 all_points = [] 6 for i in data: 7 temp = [] 8 for j in data: 9 temp.append(ecludDist(i,j)) 10 all_points.append(temp) 11 return all_points

  3、點種類的劃分:

 1 def classify(z):   #z為通過歐式距離計算所得的矩陣
 2     pts = []
3 for row in z: 4 density = np.sum(z.ix[row] < eps) 5 pts = 0 6 if density > MinPts: 7 pts = 1 #核心點 8 elif density > 1: 9 pts = 2    #邊界點 10 else: 11 pts = 0    #離群點 12 pts.append(pts) 13 return
pts

  4、將每個點的領域作為一個類:

 1 def point_type:
 2     cluster = dict()
 3     i = 0
 4     for row in z:
 5         cluster[i] = np.where(z.ix[row] < eps)[0]
 6         i = i+1
 7     for i in range(len(cluster)):
 8         for j in range(len(cluster)):
 9             if len(set(cluster[i]) & set(cluster[j])) > 0 and i!=j:
10                 cluster[i] = cluster[i] | cluster[j]
11                 cluster[j] = []

  5、找出獨立的領域

1 def independent_filed(cluster):
2     j = 0
3     result = dict()
4     for i in range(len(cluster)):
5         if len(cluster[i]) >0:    
6             result[j] = cluster[i]
7             j =j+1
8     return result

  6、對最後聚類的結果標記

 1 def mark(df):    #傳進來的是轉換後的資料
 2     for i in range(result):   #result 為一個字典型結構
 3         for j in result[i]:
 4             df.at[j,'type'] = i     #新建一列,並給它把i值新增上去
 5 
 6 
 7 plt.scatter(
 8     df['one'],
 9     df['two'],
10     c=df['type'])
11     

最後把這些函式封裝一下就Ok啦