DBSCAN——非凸数据集聚类

本文通过实例展示了DBSCAN算法在非凸数据分布上的应用,对比K-Means算法,DBSCAN能更准确地识别非凸区域,适用于复杂形状的聚类分析。通过调整参数eps和min_samples,可以有效区分不同密度的簇和噪声点。

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)
### 分析方法 DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一种基于密度的空间聚类算法,对噪声不敏感,能发现任意形状的聚类,但聚类结果与参数有很大关系。在进行基于DBSCAN算法的鸢尾花数据集聚分析时,可按以下步骤进行: 1. **数据准备**:获取鸢尾花数据,通常使用`sklearn`库中的`datasets.load_iris()`函数来加载。 2. **数据预处理**:将数据划分为特征和标签,特征用于聚类分析,标签用于后续评估聚类结果。 3. **模型训练**:使用DBSCAN算法对特征数据进行聚类,需要设置合适的参数,如`eps`(邻域半径)和`min_samples`(邻域内最小样本数)。 4. **结果评估**:将聚类结果与真实标签进行对比,评估聚类的准确性。 ### 代码示例 ```python from sklearn.datasets import load_iris from sklearn.cluster import DBSCAN from sklearn.metrics import adjusted_rand_score import matplotlib.pyplot as plt import numpy as np # 加载鸢尾花数据 iris = load_iris() X = iris.data # 特征数据 y = iris.target # 真实标签 # 创建DBSCAN模型 dbscan = DBSCAN(eps=0.5, min_samples=5) # 训练模型并进行聚类 labels = dbscan.fit_predict(X) # 评估聚类结果 ari = adjusted_rand_score(y, labels) print(f"Adjusted Rand Index: {ari}") # 可视化聚类结果 plt.figure(figsize=(10, 6)) plt.scatter(X[:, 0], X[:, 1], c=labels, cmap='viridis') plt.title('DBSCAN Clustering of Iris Dataset') plt.xlabel('Sepal Length') plt.ylabel('Sepal Width') plt.show() ``` ### 代码解释 1. **数据加载**:使用`load_iris()`函数加载鸢尾花数据,将特征数据存储在`X`中,真实标签存储在`y`中。 2. **模型创建**:使用`DBSCAN`创建模型,设置`eps=0.5`和`min_samples=5`作为参数。 3. **模型训练与聚类**:使用`fit_predict()`方法对特征数据进行聚类,并将聚类结果存储在`labels`中。 4. **结果评估**:使用`adjusted_rand_score()`函数计算聚类结果与真实标签之间的调整兰德指数(ARI),评估聚类的准确性。 5. **可视化**:使用`matplotlib`库绘制散点图,将聚类结果可视化。 ### 注意事项 - DBSCAN算法的聚类结果与参数`eps`和`min_samples`密切相关,需要根据数据的特点进行调整。 - 由于DBSCAN算法会将噪声点标记为 -1,因此在评估聚类结果时需要注意处理这些噪声点。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

颹蕭蕭

白嫖?

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

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

打赏作者

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

抵扣说明:

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

余额充值