一提到密度聚类,脑海中立马就能呈现出一个聚类结果图,不自然的就感觉非常的简单,不就是基于密度的聚类嘛,原理不用看也懂了,但是真的实现起来,仿佛又不知道从哪里开始下手。这时候再仔细回想一下脑海中的密度聚类结果图,好像和K-means聚类的结果图是一样的,那真实的密度聚类是什么样子的呢?看了西瓜书的伪代码后还是没法实现?今天小编就带大家解决一下密度聚类的难点。
实现一个神经网络,一定一定要先明白这个网络的结构,**输入是什么?输出是什么?网络的层级结构是什么?权值是什么?每个节点代表的是什么?网络的工作流程是什么?**
对于密度聚类,有两个关键的要素,一个是密度的最小值,另一个是两个样本之间的最大距离。规定了密度最小值就规定了核心样本邻域包含数据的最小值,规定两个样本之间的最大距离就规定了两个样本相聚多远才算是一类。而且,这两个值都是需要不断测试之后才选取的,并不是一次就那么容易定下来的。另一个需要了解的就是,密度聚类中有 **核心对象、密度直达、密度可达、和密度相连** ,这几个概念。
核心对象就是指的一个类的核心,满足两个条密度聚类的关键要素,初始的核心对象有很多,但是经过不断迭代整合后,核心对象越来越少,到最后一个类形成后,核心对象就是一个抽象的概念,并不能明确的指出这个类的核心对象是哪一个,但一定是初始核心对象中的一个。初始的核心对象的邻域中,一定包含多个核心对象。
用下图来区分密度直达,密度可达和密度相连,假设X1为核心对象,那么X1和X2密度直达,X1和X3是密度可达,X3和X4是密度相连。密度相连就是两个相聚比较远的边缘节点了,密度直达和密度可达距离都比较近。
我们先理清一下密度聚类的过程:
- 首先要找到核心对象,即满足周围数据距离小于密度最小值的数据数量大于密度最小值,并且记录下核心对象的邻居节点。
- 随机选取一个核心对象,找到对应的邻居节点,即密度直达的节点,查看邻居节点中包含的核心对象,将这几个节点记录下来,并在核心对象列表中删除包含的核心对象,然后依次遍历这几个核心对象和它们的邻居,按照相同的方法,记录下的就是密度可达的节点。在遍历开始时,添加一个判断条件,判断这个节点是不是满足核心节点的条件,如果不满足,那么就不再查找它的邻域,这些节点就是密度相连节点,也就是这一个类的边缘节点。
下面就是整个密度聚类的代码:
#密度聚类
import numpy as np
import random
import time
import copy
np.set_printoptions(suppress=True)
def euclidean_distance(x, w): # 欧式距离公式√∑(xi﹣wi)²
return round(np.linalg.norm(np.subtract(x, w), axis=-1),8)
def find_neighbor(j, x, eps):
N = list()
for i in range(x.shape[0]):
temp = euclidean_distance(X[i],X[j]) # 计算欧式距离
print(str(j)+"到",str(i)+"的距离",'%.8f' % temp)
if temp <= eps:
N.append(i)
return set(N)
def DBSCAN(X, eps, min_Pts):
k = -1
neighbor_list = [] # 用来保存每个数据的邻域
omega_list = [] # 核心对象集合
gama = set([x for x in range(len(X))]) # 初始时将所有点标记为未访问
cluster = [-1 for _ in range(len(X))] # 聚类
for i in range(len(X)):
neighbor_list.append(find_neighbor(i, X, eps))
if len(neighbor_list[-1]) + int(count_matrix[i]) >= min_Pts: #如果权值对应位置的数据样本数量和相似权值的数量之和大于一定的数
omega_list.append(i) # 将样本加入核心对象集合
omega_list = set(omega_list) # 转化为集合便于操作
while len(omega_list) > 0:
gama_old = copy.deepcopy(gama) #上一状态未访问的节点
j = random.choice(list(omega_list)) # 随机选取一个核心对象
k = k + 1 #第几个类别
Q = list()
Q.append(j) #选出来的核心对象
gama.remove(j) #标记为访问过
while len(Q) > 0:#初始Q只有一个,但是后面会扩充
q = Q[0]
Q.remove(q) #把遍历完的节点删除
#正是下面这一个if决定了密度聚类的边缘,不满足if语句的就是密度相连,满足就是密度直达或者密度可达
if len(neighbor_list[q]) >= min_Pts:#验证是不是核心对象,找出密度直达
delta = neighbor_list[q] & gama #set的交集,邻域中包含的未访问过的数据
deltalist = list(delta)
for i in range(len(delta)):
Q.append(deltalist[i])#将没访问过的节点添加到队列
gama = gama - delta #节点标记为访问
Ck = gama_old - gama #记录这一类中的节点
Cklist = list(Ck)
for i in range(len(Ck)):
cluster[Cklist[i]] = k #标记这一类的数据
omega_list = omega_list - Ck #删除核心对象
return cluster
加载数据
X = np.load("文件位置")
X = X.reshape((-1,向量维度)) #修改维度
eps = 0.0000002 #两个样本之间的最大距离
min_Pts = 20 #样本的最小值
C = DBSCAN(X, eps, min_Pts)
C = np.array(C)
np.save("classify.npy",C)
print("C",C.reshape([X原来的维度]))
注意一点,密度聚类的输入数据,不管是多少维,用这个代码的话都要转换成一维数据再进行密度聚类。举个例子,二维数据row行,loc列,那么数据reshape成一维数据后,当前位置 i 对应的位置就是[(row*loc)+i]。如果有不懂或者有任何问题,欢迎留言讨论!
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。
举报投诉
-
核心
+关注
关注
0文章
42浏览量
14993 -
对象
+关注
关注
1文章
38浏览量
17291 -
密度聚类
+关注
关注
0文章
3浏览量
5717
发布评论请先 登录
相关推荐
基于模糊聚类表征的音频例子检索及相关反馈
避免先前基于例子的音频检索要按照监督机制训练不同类别的复杂的音频模板,直接从原始音频流中提取压缩域特征,使用时空约束机制进行压缩域特征的模糊聚类,用聚类结果的质心来表征整个音频例子,基
发表于 03-06 22:10
请教51用的聚类算法
在一个数组中使用聚类算法找出重复出现的数组元素,然后使用其他字符表示,达到减少储存空间的作用,有哪位大哥做过相关的项目吗?希望可以赐教一下或者有偿提供服务也可以!
发表于 03-09 23:07
深非监督学习-Hierarchical clustering 层次聚类python的实现
【深度学习基础-17】非监督学习-Hierarchical clustering 层次聚类-python实现
发表于 04-28 10:07
一种基于聚类和竞争克隆机制的多智能体免疫算法
包含分布式电源的配电网无功优化matlab源代码,代码按照高水平文章复现,保证正确,可先发您文章看是否满足您的要求利用分布式电源的无功补偿能力,提出了一种基于聚类和竞争克隆机制的多智能
发表于 12-29 06:50
基于数据划分和融合策略的并行DBSCAN算法
的项归为一类,而将不具有该特征的项排除在外。主流的聚类方法包括基于划分的聚类方法,如K-means;层次聚类方法,如CURE和BIRCH等;基于统计模型的方法,如EM算法等;基于密度的方法,如DBSCAN,OPTICS等。在基于密度
发表于 02-08 14:58
•0次下载
评论