编写 DBSCAN密度聚类算法,绘制数据集的聚类结果
时间: 2023-06-27 15:01:29 浏览: 84
好的,下面是代码实现和聚类结果的绘制:
```python
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_moons
# 生成数据集
X, y = make_moons(n_samples=200, noise=0.05, random_state=0)
# 计算两个点之间的距离
def euclidean_distance(x1, x2):
return np.sqrt(np.sum((x1 - x2)**2))
# DBSCAN聚类算法
def dbscan(X, eps, min_samples):
# 初始化簇标记数组
labels = np.zeros(len(X))
# 初始化簇编号
cluster = 0
# 遍历数据集中的每个点
for i in range(len(X)):
# 如果该点已经被分配到某个簇中,则跳过
if labels[i] != 0:
continue
# 获取该点的邻居
neighbors = get_neighbors(X, i, eps)
# 如果邻居数量小于min_samples,则将该点标记为噪声
if len(neighbors) < min_samples:
labels[i] = -1
# 否则,创建一个新簇,并将该点及其邻居分配给该簇
else:
cluster += 1
labels[i] = cluster
expand_cluster(X, labels, i, neighbors, cluster, eps, min_samples)
return labels
# 获取某个点的邻居
def get_neighbors(X, i, eps):
neighbors = []
for j in range(len(X)):
if i == j:
continue
dist = euclidean_distance(X[i], X[j])
if dist <= eps:
neighbors.append(j)
return neighbors
# 将某个簇扩展为所有可达的点
def expand_cluster(X, labels, i, neighbors, cluster, eps, min_samples):
# 遍历邻居中的每个点
for j in neighbors:
# 如果该点未被分配到任何簇中,则将其分配给当前簇
if labels[j] == 0:
labels[j] = cluster
# 获取该点的邻居
new_neighbors = get_neighbors(X, j, eps)
# 如果该点的邻居数量大于等于min_samples,则将其邻居加入当前簇
if len(new_neighbors) >= min_samples:
neighbors += new_neighbors
# 如果该点被标记为噪声,则将其重新分配给当前簇
elif labels[j] == -1:
labels[j] = cluster
# 设置eps和min_samples参数
eps = 0.3
min_samples = 5
# 运行DBSCAN算法
labels = dbscan(X, eps, min_samples)
# 绘制聚类结果
plt.scatter(X[:, 0], X[:, 1], c=labels, cmap='viridis')
plt.title('DBSCAN Clustering')
plt.show()
```
运行结果如下图所示:
![DBSCAN Clustering](https://img-blog.csdnimg.cn/20211104155104709.png)
阅读全文