python 密度聚类_DBSCAN密度聚类

本文介绍了一个使用Python实现的DBSCAN密度聚类算法,详细展示了算法的代码实现,并通过实例解释了DBSCAN的主要优缺点。DBSCAN能够处理任意形状的数据集,对异常点敏感,但对参数调优有一定要求。
摘要由CSDN通过智能技术生成

# coding:utf-8

"""

@author = LPS

"""

import numpy as np

import matplotlib.pyplot as plt

data = np.loadtxt('moon.txt')

n,m = data.shape

all_index = np.arange(n)

dis = np.zeros([n,n])

data = np.delete(data, m-1, axis=1)

def dis_vec(a,b): # 计算两个向量的距离

if len(a)!=len(b):

return Exception

else:

return np.sqrt(np.sum(np.square(a-b)))

for i in range(n): # 计算距离矩阵

for j in range(i):

dis[i,j] = dis_vec(data[i],data[j])

dis[j,i] = dis[i,j]

def dbscan(s, minpts): # 密度聚类

center_points = [] # 存放最终的聚类结果

k = 0 # 检验是否进行了合并过程

for i in range(n):

if sum(dis[i] <= s) >= minpts: # 查看距离矩阵的第i行是否满足条件

if len(center_points) == 0: # 如果列表长为0,则直接将生成的列表加入

center_points.append(list(all_index[dis[i] <= s]))

else:

for j in range(len(center_points)): # 查找是否有重复的元素

if set(all_index[dis[i] <= s]) & set(center_points[j]):

center_points[j].extend(list(all_index[dis[i] <= s]))

k=1 # 执行了合并操作

if k==0 :

center_points.append(list(all_index[dis[i] <= s])) # 没有执行合并说明这个类别单独加入

k=0

lenc = len(center_points)

# 以下这段代码是进一步查重,center_points中所有的列表并非完全独立,还有很多重复

# 那么为何上面代码已经查重了,这里还需查重,其实可以将上面的步骤统一放到这里,但是时空复杂的太高

# 经过第一步查重后,center_points中的元素数目大大减少,此时进行查重更快!

k = 0

for i in range(lenc-1):

for j in range(i+1, lenc):

if set(center_points[i]) & set(center_points[j]):

center_points[j].extend(center_points[i])

center_points[j] = list(set(center_points[j]))

k=1

if k == 1:

center_points[i] = [] # 合并后的列表置空

k = 0

center_points = [s for s in center_points if s != []] # 删掉空列表即为最终结果

return center_points

if __name__ == '__main__':

center_points = dbscan(0.2,10) # 半径和元素数目

c_n = center_points.__len__() # 聚类完成后的类别数目

print (c_n)

ct_point = []

color = ['g','r','b','m','k']

noise_point = np.arange(n) # 没有参与聚类的点即为噪声点

for i in range(c_n):

ct_point = list(set(center_points[i]))

noise_point = set(noise_point)- set(center_points[i])

print (ct_point.__len__()) # 输出每一类的点个数

print (ct_point) # 输出每一类的点

print ("**********")

noise_point = list(noise_point)

for i in range(c_n):

ct_point = list(set(center_points[i]))

plt.scatter(data[ct_point,0], data[ct_point,1], color=color[i]) # 画出不同类别的点

plt.scatter(data[noise_point,0], data[noise_point,1], color=color[c_n], marker='h', linewidths=0.1) # 画噪声点

plt.show()

DBSCAN的主要优点有:

1) 可以对任意形状的稠密数据集进行聚类,相对的,K-Means之类的聚类算法一般只适用于凸数据集。

2) 可以在聚类的同时发现异常点,对数据集中的异常点不敏感。

3) 聚类结果没有偏倚,相对的,K-Means之类的聚类算法初始值对聚类结果有很大影响。

DBSCAN的主要缺点有:

1)如果样本集的密度不均匀、聚类间距差相差很大时,聚类质量较差,这时用DBSCAN聚类一般不适合。

2) 如果样本集较大时,聚类收敛时间较长,此时可以对搜索最近邻时建立的KD树或者球树进行规模限制来改进。

3) 调参相对于传统的K-Means之类的聚类算法稍复杂,不同的参数组合对最后的聚类效果有较大影响。

实验:

原图                                                   square4  e=0.85  minpts = 13                                            square4-sklearn e=0.9 minpts=15

                       

原图                                                                                                                         结果图

  

原图                                                                       square1 1.185,8                                                                square1   0.85 15

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值