聚类算法:DBSCAN
来源:互联网 发布:性价比高的相机 知乎 编辑:程序博客网 时间:2024/05/12 20:43
DBSCAN:是一种简单的,基于密度的聚类算法。本次实现中,DBSCAN使用了基于中心的方法。在基于中心的方法中,每个数据点的密度通过对以该点为中心以边长为2*EPs的网格(邻域)内的其他数据点的个数来度量。根据数据点的密度分为三类点:
(2)边界点:该点不是核心点,但是其邻域内包含至少一个核心点。
(3)噪音点:不是核心点,也不是边界点。
有了以上对数据点的划分,聚合可以这样进行:各个核心点与其邻域内的所有核心点放在同一个簇中,把边界点跟其邻域内的某个核心点放在同一个簇中。
根据该算法,实现如下代码:
# scoding=utf-8import pylab as plfrom collections import defaultdict,Counter points = [[int(eachpoint.split("#")[0]), int(eachpoint.split("#")[1])] for eachpoint in open("points","r")] # 计算每个数据点相邻的数据点,邻域定义为以该点为中心以边长为2*EPs的网格Eps = 10surroundPoints = defaultdict(list)for idx1,point1 in enumerate(points): for idx2,point2 in enumerate(points): if (idx1 < idx2): if(abs(point1[0]-point2[0])<=Eps and abs(point1[1]-point2[1])<=Eps): surroundPoints[idx1].append(idx2) surroundPoints[idx2].append(idx1) # 定义邻域内相邻的数据点的个数大于4的为核心点MinPts = 5corePointIdx = [pointIdx for pointIdx,surPointIdxs in surroundPoints.iteritems() if len(surPointIdxs)>=MinPts] # 邻域内包含某个核心点的非核心点,定义为边界点borderPointIdx = []for pointIdx,surPointIdxs in surroundPoints.iteritems(): if (pointIdx not in corePointIdx): for onesurPointIdx in surPointIdxs: if onesurPointIdx in corePointIdx: borderPointIdx.append(pointIdx) break # 噪音点既不是边界点也不是核心点noisePointIdx = [pointIdx for pointIdx in range(len(points)) if pointIdx not in corePointIdx and pointIdx not in borderPointIdx] corePoint = [points[pointIdx] for pointIdx in corePointIdx] borderPoint = [points[pointIdx] for pointIdx in borderPointIdx]noisePoint = [points[pointIdx] for pointIdx in noisePointIdx] # pl.plot([eachpoint[0] for eachpoint in corePoint], [eachpoint[1] for eachpoint in corePoint], 'or')# pl.plot([eachpoint[0] for eachpoint in borderPoint], [eachpoint[1] for eachpoint in borderPoint], 'oy')# pl.plot([eachpoint[0] for eachpoint in noisePoint], [eachpoint[1] for eachpoint in noisePoint], 'ok') groups = [idx for idx in range(len(points))] # 各个核心点与其邻域内的所有核心点放在同一个簇中for pointidx,surroundIdxs in surroundPoints.iteritems(): for oneSurroundIdx in surroundIdxs: if (pointidx in corePointIdx and oneSurroundIdx in corePointIdx and pointidx < oneSurroundIdx): for idx in range(len(groups)): if groups[idx] == groups[oneSurroundIdx]: groups[idx] = groups[pointidx] # 边界点跟其邻域内的某个核心点放在同一个簇中for pointidx,surroundIdxs in surroundPoints.iteritems(): for oneSurroundIdx in surroundIdxs: if (pointidx in borderPointIdx and oneSurroundIdx in corePointIdx): groups[pointidx] = groups[oneSurroundIdx] break # 取簇规模最大的5个簇wantGroupNum = 3finalGroup = Counter(groups).most_common(3)finalGroup = [onecount[0] for onecount in finalGroup] group1 = [points[idx] for idx in xrange(len(points)) if groups[idx]==finalGroup[0]]group2 = [points[idx] for idx in xrange(len(points)) if groups[idx]==finalGroup[1]]group3 = [points[idx] for idx in xrange(len(points)) if groups[idx]==finalGroup[2]] pl.plot([eachpoint[0] for eachpoint in group1], [eachpoint[1] for eachpoint in group1], 'or')pl.plot([eachpoint[0] for eachpoint in group2], [eachpoint[1] for eachpoint in group2], 'oy')pl.plot([eachpoint[0] for eachpoint in group3], [eachpoint[1] for eachpoint in group3], 'og') # 打印噪音点,黑色pl.plot([eachpoint[0] for eachpoint in noisePoint], [eachpoint[1] for eachpoint in noisePoint], 'ok') pl.show()
因为DBSCAN使用簇的基于密度的定义,因此它是相对抗噪音的,并且能处理任意形状和大小的簇。但是如果簇的密度变化很大,例如ABCD四个簇,AB的密度大大大于CD,而且AB附近噪音的密度与簇CD的密度相当,这是当MinPs较大时,无法识别簇CD,簇CD和AB附近的噪音都被认为是噪音;当MinPs较小时,能识别簇CD,但AB跟其周围的噪音被识别为一个簇。这个问题可以基于共享最近邻(SNN)的聚类结局。
0 0
- 聚类算法:DBSCAN
- DBSCAN聚类算法
- DBSCAN 聚类算法
- DBSCAN聚类算法
- DBSCAN聚类算法
- DBSCAN聚类算法
- 聚类算法:DBScan算法
- DBSCAN聚类算法原理
- DBSCAN聚类算法原理
- 密度聚类算法DBScan
- 聚类算法(二):DBSCAN算法
- 从DBSCAN算法谈谈聚类算法
- R聚类算法-DBSCAN算法
- 聚类算法-dbscan算法的研究
- 聚类算法之DBScan(Java实现)
- DBSCAN聚类算法C++实现
- 聚类算法之DBScan(Java实现)
- 聚类算法初探(五)DBSCAN
- JavaScript跨域总结与解决办法
- postgresql 数据库使用手册
- cJSON代码阅读(10)——把数值构造成JSON格式
- UML类图关系
- spring AOP 原理讲解
- 聚类算法:DBSCAN
- Publish Android App 为灰色不可点击
- 仿微信弹出“生日快乐”类动画
- Win Server2008 服务器远程连接数量设置
- 【慕课笔记】第一章 JAVA初体验 第5节 MyEclipse的使用简介
- java基础的一些区别
- mysql 设置密码
- mkdir 0755 failed
- MongoDB安装问题解决