python实现DBSCAN

DBSCAN聚类算法学习及实践

一、 原理学习

DBSCAN聚类算法是基于密度的聚类算法。该算法适合稠密的数据集的分类,但是对于密度不均匀聚类间距大的数据集聚类的质量较差。该算法可以自行对数据集的聚类数量做出判断,同时对于异常点可以在聚类的时候发现。

二、实验结果

a、使用sklearn的datasets.make_circles生成的随机二维数据。

初始参数设置为ϵ=0.4, MinPts =3,发现如图1-1所示,只有一个类。想要增加类别可通过降低参数ϵ或者增大参数MinPts。首先通过降低ϵ值,一直试验到0.1发现已经最好了出现如图1-2所示结果,但是中间应当是两个类,故再次通过增大MinPts值,最终发现将值设置为6时出现三个类,如图1-3所示。得到最终参数设置e ϵ=0.1, MinPts =6。


在这里插入图片描述
图1-1 ϵ=0.4, MinPts =3


在这里插入图片描述
图1-1 ϵ=0.1, MinPts =3


在这里插入图片描述
图1-3 ϵ=0.1, MinPts =6

b、对iris数据集试验

对数据集的三四两个维度的特征属性进行调参(降低ϵ值或者增大MinPts值可增加类别),得到图1-1和图1-2所示的结果。图1-1显示为ϵ=0.4, MinPts =5的结果,可以看出分为两个类时聚类效果很好,但是数据集是三个类的数据。故将参数调整到ϵ=0.2, MinPts =5,得到图1-2所示的结果,这时因为后两个类的间距和第一个类的间距差别较大,也就是密度不均匀因而聚类的效果不好。

在这里插入图片描述
图2-1 ϵ=0.4, MinPts =5

在这里插入图片描述
图2-2 ϵ=0.2, MinPts=5

对数据集的一二两个维度的特征属性进行调参,得到图1-3所示的结果。从图中可以看出所得聚类结果还算可以,但是在红色的聚类附近大量的噪音点肉眼感觉可将其归入,这就是密度的不均匀造成的。对一到四这四个维度的特征值进行聚类得到了图1-4所示的结果,结果为47/38/36。此效果图是通过三四两个维度绘制,所以看起来可能会有些出入,总体效果还是相对较好的。

图1-3 ϵ=0.2, MinPts =5
图2-3 ϵ=0.2, MinPts =5

在这里插入图片描述
图2-4 ϵ=0.4, MinPts=4


P.S.代码参考及使用sklearn实现。

import matplotlib.pyplot as plt  
import numpy as np  
from sklearn.cluster import KMeans
from sklearn import datasets 
from  sklearn.cluster import DBSCAN
 
# wine = datasets.load_wine() 
# X = wine.data[:, :13]  # #表示我们只取特征空间中的4个维度
iris = datasets.load_iris()
X = iris.data[:,:4]
# X1, y1=datasets.make_circles(n_samples=5000, factor=.6,
#                                        noise=.05)
# X2, y2 = datasets.make_blobs(n_samples=1000, n_features=2, centers=[[1.2,1.2]], cluster_std=[[.1]],
#                 random_state=9)
# X = np.concatenate((X1, X2))
print(X.shape)
# 绘制数据分布图
# plt.scatter(X[:, 0], X[:, 1], c="red", marker='o', label='see')  
# plt.xlabel('petal length')  
# plt.ylabel('petal width')  
# plt.legend(loc=2)  
# plt.show() 

 
# :2   0.2,5
# 2:4  0.4,5  0.2 5
# :4   0.4,4
# datasets.make_circles  eps=0.1, min_samples=6
dbscan = DBSCAN(eps=0.4, min_samples=4)
dbscan.fit_predict(X) 
#fit_predict
label_pred = dbscan.labels_

color = ["red","blue","green","gray","black"]
marker = ['o','*','+',]
for i in range(max(label_pred)):
	x = X[label_pred == i]
	print(len(x))
	plt.scatter(x[:, 2], x[:, 3], c=color[i%5], marker=marker[i%3], label='class'+ str(i+1) + '-' + str(len(x)))

x1 = X[label_pred == 3]
print(len(x1))
plt.scatter(x1[:, 2], x1[:, 3], c=color[-1], marker=marker[-1])
x = X[label_pred == -1]
print(len(x))
plt.scatter(x[:, 2], x[:, 3], c=color[-1], marker=marker[-1], label='noise' + '-' + str(len(x)+len(x1)))
 
# 绘制k-means结果 
# plt.xlabel('petal length')  
# plt.ylabel('petal width')  
plt.legend(loc=2)  
plt.show()  

  • 2
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值