聚类算法(二):DBSCAN算法

来源:互联网 发布:欢乐牛牛源码 编辑:程序博客网 时间:2024/05/19 22:06

首先确保你在动手写代码之前已经了解什么是聚类分析。

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 randomimport mathimport copydef 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 clusterdef 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 Ndef 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


0 0
原创粉丝点击