首先确保你在动手写代码之前已经了解什么是聚类分析。
DBSCAN算法----一种基于密度的聚类算法。DBSCAN算法是如何发现簇的呢?
1.首先,给定数据集D中的所有对象都被标记为unvisited
2.随机的选择一个未访问的对象p,标记为visited
3.检查p的e-邻域是否至少包含MinPts个点
4.如果不是则标记为噪声点,否则为p创建一个簇C,并且把p的e-邻域中的所有对象都放到候选集合N中
5.DBSCAN迭代的把N中不属于其它簇的对象添加到C中。在此过程中,对于N中标记为unvisited的对象p‘,DBSCAN把它标记为visited,并检查它的e-邻域对象。
6.如果p’的e-邻域至少有MinPts个对象,则p‘的e-邻域中的对象全部添加到N中
7.DBSCAN继续添加对象到C中,知道C不能再被扩充位置,至此N就空了。此时簇C被生成,于是被输出
源码(Python)
import random import math import copy def DBSCAN(data, e, MinPts): visited = [] # 已访问的成员 C = [] # 一个新的簇C cluster = [] unvisited = copy.deepcopy(data) # 对所有对象标记为unvisited while unvisited != []: # 如果还有未被探索的点则继续循环 mark = random.randint(0, len(unvisited)-1) p = unvisited[mark] # 在unvisited中随机选择一个p点 visited.append(p) # 标记p点为visited unvisited.pop(mark) #将p从unvisited中pop掉 N = Naghbor(data, e, p) if len(N) >= MinPts: # 如果邻域中至少有MinPts个对象的话 C.append(p) #将p添加到一个新的簇C中 i = 0 while i <= len(N)-1: pp = N[i] if pp in unvisited: #如果pp未被探索 visited.append(pp) #标记为visited unvisited.pop(unvisited.index(pp)) NN = Naghbor(data, e, pp) if len(NN) >= MinPts: # pp的e邻域至少有MinPts个点 for j in range(len(NN)): if NN[j] not in N: N.append(NN[j]) #把这些邻域点都放进N中,记得去重复 #如果pp不在任何簇中,将pp添加到簇C中 #---------------------------# flag = 0 for k in range(len(cluster)): if pp not in cluster[k]: flag += 1 if flag == len(cluster): #如果pp不在任何簇集合中,将pp添加到簇C中 C.append(pp) #---------------------------# flag = 0 # flag归0 i += 1 # N的标志位+1 else: i += 1 if len(C) > 1: cluster.append(C) # 将C添加到簇集合中 C = [] return cluster def Naghbor(data, e, p): # 计算p点的e邻域点 N = [] len_data = len(data) for i in range(len_data): distance_p = Distance(p, data[i]) if distance_p<=e and distance_p!=0: #待测点在e邻域之内,且不是自身 N.append(data[i]) return N def Distance(point1, point2): #计算两点欧氏距离 if point1 == point2: return 0 else: dis_x = point2[0] - point1[0] dis_y = point2[1] - point1[1] dis = math.sqrt(dis_x**2 + dis_y**2) return dis
刚开始将所有data置为unvisited时,常人都会这样想:
unvisited = data
unvisited = copy.deepcopy(data)
http://blog.csdn.net/chixujohnny/article/details/50340213