DBSCAN——非凸数据集聚类

K-Means 本质上是将样本空间划分成 k 个 Voronoi 区域,决定了划分结果的 k 个簇一定是凸集,因而该方法对非凸区域的鉴别效果非常不好。
在这里插入图片描述
下面使用 DBSCAN 对上面非凸分布的数据聚类。
本例中 DBSCAN 选择的参数为:eps=0.5, min_samples=5
即要求一个团簇内点(非边界、非噪声点)在半径为 eps 的范围内至少有 min_sample 个点,边界点至少在满足上述条件一个内点的 eps 范围内,其余为噪声点。


import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import DBSCAN

def show_scatter(data,colors):
    cm = plt.cm.get_cmap('Spectral')
    x,y = data.T
    plt.scatter(x,y,c=colors,cmap=cm)
    plt.axis()
    plt.xlabel("x")
    plt.ylabel("y")

db = DBSCAN(eps=0.5, min_samples=5).fit(data)

labels = set(db.labels_)
n_clusters = len(labels) - (1 if -1 in labels else 0)
noise_mask = (db.labels_ == -1)
colors = [plt.cm.Spectral(each)
          for each in np.linspace(0, 1, len(labels))]

plt.title('Estimated number of clusters: %d' % n_clusters)
show_scatter(data[~noise_mask],db.labels_[~noise_mask])
show_scatter(data[noise_mask],'k')
plt.show()

在这里插入图片描述
图中的黑点为 DBSCAN 算法得出的噪声点。

生成上图数据的函数如下:

def gen_ring(r, var, num):
    r_array = np.random.normal(r,var,num)
    t_array = [ np.random.random()*2*np.math.pi for i in range(num)]
    data = [[r_array[i]*np.math.cos(t_array[i]),
             r_array[i]*np.math.sin(t_array[i])] 
            for i in range(num)]
    return data

def gen_gauss(mean,cov,num):     
    return np.random.multivariate_normal(mean,cov,num)
    
def gen_clusters():
    data = gen_ring(1,0.1,100)
    data = np.append(data,gen_ring(3,0.1,300),0)
    data = np.append(data,gen_ring(5,0.1,500),0)
    mean = [7,7]
    cov = [[0.5,0],[0,0.5]]
    data = np.append(data,gen_gauss(mean,cov,100),0)
    return np.round(data,4)
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

颹蕭蕭

白嫖?

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值