一、简要介绍
DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一种常用的密度聚类算法,适用于发现任意形状的聚类簇,并且可以有效处理噪声数据。以下是关于DBSCAN的简要介绍:
-
密度概念:
- DBSCAN基于密度的概念进行聚类,它定义了两个重要的参数:ϵ(邻域半径)和 MinPts(最小点数)。
- ϵ指定了一个样本点的邻域范围,MinPts定义了一个核心点所需的邻域内最少样本点数量。
-
核心点、边界点和噪声点:
- 核心点:在其ϵ-邻域内至少包含MinPts个样本点的点被称为核心点。
- 边界点:在其ϵ-邻域内包含少于MinPts个样本点,但位于核心点的邻域内的点被称为边界点。
- 噪声点:既不是核心点也不是边界点的点被称为噪声点。
-
聚类过程:
- DBSCAN从一个未访问的样本点开始,探索其ϵ-邻域内的点。
- 如果该点是核心点,则以该点为中心展开一个聚类;如果是边界点,则将其加入到与其关联的聚类中。
- 不断重复这个过程,直到所有样本点都被访问过。
-
算法特点:
- 能够有效识别任意形状的聚类簇,不受聚类形状的限制。
- 能够处理噪声点,将其识别为单独的噪声簇。
- 不需要预先指定簇的数量,由算法自动确定。
-
参数选择:
- ϵ 和 MinPts 的选择对聚类结果有重要影响,需要根据数据集的特点进行调优。
总的来说,DBSCAN是一种强大的聚类算法,适用于处理具有不规则形状和噪声的数据集。通过基于密度的思想,DBSCAN能够高效地发现聚类簇,并适应不同类型的数据集。
相较于K-MEANS的一个显著优点是不需要事先知道要分成多少个簇,这对于解决“求数据有几类”的聚类问题很有效。但需要注意对ϵ 和 MinPts 的选择依赖于反复试验得到合适的经验值。
二、示例代码
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import DBSCAN# 生成一个包含30个随机整数的数组(1~100)
data = np.random.randint(1, 101, size=30)
# data=np.array([12, 14, 45, 65, 48, 99, 97, 94, 85, 13, 8, 66, 42, 87, 35, 27, 24, 4, 5, 84])
# 转换为二维数组以便于绘图(添加一个常数维度)
data_2d = data.reshape(-1, 1)
# 定义DBSCAN参数
eps = 7
min_samples = 3
# 应用DBSCAN算法
db = DBSCAN(eps=eps, min_samples=min_samples)
db.fit(data_2d)
# 获取聚类标签
labels = db.labels_# 创建颜色映射
unique_labels = set(labels)
colors = plt.cm.Spectral(np.linspace(0, 1, len(unique_labels)))
# 绘制散点图,不同颜色代表不同簇
plt.figure(figsize=(10, 6))
for k, col in zip(unique_labels, colors):if k == -1: # -1代表噪声点,通常用灰色表示col = (0.5, 0.5, 0.5)class_member_mask = (labels == k)xy = data_2d[class_member_mask]plt.plot(xy[:, 0], [0] * len(xy), 'o', markerfacecolor=col, markeredgecolor='k', markersize=14)
plt.xlabel('Value')
plt.title('DBSCAN Clustering on 1D Data')
plt.grid(True)
plt.show()# 获取不包括噪声点的聚类数量
n_clusters = len(set(labels)) - (1 if -1 in labels else 0)
print(f"根据设定的参数,数据被分为{n_clusters}个簇(不包括噪声点)")
# 包括噪声点作为一类
n_clusters_including_noise = len(set(labels))
print(f"包括噪声点在内,数据被分为{n_clusters_including_noise}个类别")
# -*- coding :utf-8 -*-
# @FileName :Clustering.py
# @Time :2024/3/6 0:36
# @Author :TRXCXimport numpy as np
from sklearn.cluster import DBSCAN# 参数是list,返回该list中的数据可以被分为几类(无噪声和有噪声)
def clustering(_s_data):data = np.array(_s_data)data_2d = data.reshape(-1, 1)eps = 7min_samples = 3db = DBSCAN(eps=eps, min_samples=min_samples)db.fit(data_2d)labels = db.labels_n_clusters = len(set(labels)) - (1 if -1 in labels else 0)n_clusters_including_noise = len(set(labels))return n_clusters, n_clusters_including_noiseif __name__ == '__main__':s_data = [12, 14, 45, 65, 48, 99, 97, 94, 85, 13, 8, 66, 42, 87, 35, 27, 24, 4, 5, 84]print(clustering(s_data))