已知数据点坐标,已知距离矩阵,请生成一段用近邻传播算法进行聚类的代码,最后用图片显示聚类,每个聚类都用一个圆圈包围起来
时间: 2023-05-26 16:05:56 浏览: 167
以下是近邻传播聚类算法的代码实现:
```python
import numpy as np
from matplotlib import pyplot as plt
def nearest_neighbor(data, dist):
"""
近邻传播算法的核心部分,用于计算样本之间的相似度和聚类中心
:param data: 数据集,每一行代表一个样本的特征
:param dist: 距离矩阵,每个元素代表两个样本之间的距离
:return: 聚类结果,每个元素代表一个样本所属的类别
"""
m = data.shape[0]
alpha = 0.9 # 学习率
cluster_centers = np.zeros((m, m), dtype=np.float32) # 聚类中心矩阵
for i in range(m):
for j in range(m):
# 从距离矩阵中找与当前样本相似度最高的样本
sim = np.max(dist[i, :])
idx = np.where(dist[i, :] == sim)[0][0]
# 将该样本加入到当前样本的邻居列表中
cluster_centers[idx, i] = 1.0
# 更新邻居列表中所有样本之间的相似度
for k in np.where(cluster_centers[idx, :] == 1.0)[0]:
cluster_centers[k, i] = alpha * sim + (1 - alpha) * cluster_centers[k, i]
# 聚类结果初始化为-1
labels = np.ones(m, dtype=np.int32) * -1
cluster_idx = 0
# 遍历每个样本,将该样本及其邻居归属到同一个类别中
for i in range(m):
if labels[i] != -1:
continue
neighbors = np.where(cluster_centers[i, :] > 0)[0]
labels[i] = cluster_idx
for j in neighbors:
labels[j] = cluster_idx
cluster_idx += 1
return labels
# 生成数据集和距离矩阵
np.random.seed(0)
data = np.random.rand(100, 2)
dist = np.zeros((100, 100))
for i in range(100):
for j in range(100):
dist[i, j] = np.linalg.norm(data[i] - data[j])
# 进行聚类
labels = nearest_neighbor(data, dist)
# 绘制聚类结果
colors = ['r', 'g', 'b', 'c', 'm', 'y', 'k']
plt.figure(figsize=(8, 8))
for i in range(len(set(labels))):
plt.scatter(data[labels == i][:, 0], data[labels == i][:, 1], c=colors[i], s=50)
# 绘制圆圈包围聚类结果
x_center = np.mean(data[labels == i][:, 0])
y_center = np.mean(data[labels == i][:, 1])
radius = np.max(np.linalg.norm(data[labels == i] - np.array([x_center, y_center]), axis=1))
circle = plt.Circle((x_center, y_center), radius, color=colors[i], fill=False)
plt.gca().add_patch(circle)
plt.axis('equal')
plt.show()
```
以上代码中,`nearest_neighbor`函数是近邻传播算法的核心部分,可用于计算样本之间的相似度和聚类中心;`labels`数组是聚类结果,用于记录每个样本所属的类别;最后通过绘图展示聚类结果,每个圆圈代表一个聚类。
阅读全文