import numpy as np import pandas as pd import matplotlib.pyplot as plt import heapq from scipy.spatial.distance import squareform, pdist from collections import defaultdict
init_clusters = [[i] for i in range(numberOfsamples)]
初始时每个样本是一个簇,用索引表示。
4. 构建最小堆维护簇对距离
1 2 3 4 5
for i in range(len(clusters)): for j in range(i+1, len(clusters)): dist = cluster_distance(clusters[i], clusters[j], dist_matrix, method) heapq.heappush(heap, (dist, i, j))
使用 heapq 构建最小堆,每次取出当前最近的簇对进行合并。
时间复杂度从 O(N³) 降低至 O(N² log N) 。
5. 合并簇并更新堆
1 2 3 4 5 6 7 8 9 10 11 12
while sum(valid) > numberOfcluster: while True: dist, i, j = heapq.heappop(heap) if valid[i] and valid[j]: break clusters[i].extend(clusters[j]) valid[j] = False for k in range(len(clusters)): if k != i and valid[k]: dist = cluster_distance(clusters[i], clusters[k], dist_matrix, method) heapq.heappush(heap, (dist, i, k))
def randomCenter(dataSet, k): m, n = dataSet.shape centroids = np.zeros((k, n)) for i in range(k): index = int(np.random.uniform(0, m)) centroids[i, :] = dataSet[index, :] return centroids
从数据集中随机选择 k 个样本作为初始质心 。
4. 更新质心
1 2 3 4 5 6 7 8
def update_centroids(dataSet, cluster_indices, k): centroids = np.zeros((k, dataSet.shape[1])) for j in range(k): mask = (cluster_indices == j) if np.any(mask): centroids[j] = np.mean(dataSet[mask], axis=0) return centroids
for i in range(k): plt.scatter( dataSet[clusterAssment == i, 1], dataSet[clusterAssment == i, 3], c=colors_list[i], marker=markers_list[i], label=f'Cluster {i+1}' ) plt.scatter( centroids[i, 1], centroids[i, 3], c=colors_list[i], marker='x', s=100, label='Centroids' )
plt.xlabel('Feature 0') plt.ylabel('Feature 1') plt.title(f'KMeans Clustering Result in iter num: {iter_num}') plt.legend() plt.show()
不同颜色代表不同簇。
不同标记区分簇内点与质心。
📌 五、总结
功能
描述
向量化实现
提升聚类速度,适用于大规模数据
随机初始化
简单易懂,但可能陷入局部最优
收敛判断
使用 np.allclose() 避免无限迭代
可视化支持
帮助直观理解聚类效果
📚 六、参考资料
[1] Scikit-learn 官方文档:KMeans 聚类介绍
[2] KMeans 初始化方法详解:k-means++ vs random
[3] NumPy 和 Matplotlib 在机器学习中的应用
[4] 向量化计算提高效率的方法
🧠 使用 Python 实现自定义 DBSCAN 聚类算法
DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一种基于密度的聚类算法,能够发现任意形状的簇,并且能识别出噪声点。本篇博客将带你一步步实现一个高效的 自定义 DBSCAN 算法,并使用极坐标方式生成测试样本数据集进行验证。
📦 一、环境依赖与数据准备
我们使用如下库:
1 2 3 4
import numpy as np import matplotlib.pyplot as plt from scipy.spatial.distance import cdist
Have_labeled = [] for label in cluster_centers.keys(): queue_center = cluster_centers[label].copy() Have_labeled.extend(queue_center)
while queue_center: current = queue_center.pop(0) neighbors = np.where(distances[current] < self.eps)[0] for neighbor in neighbors: if neighbor not in Have_labeled: self.labels[neighbor] = self.labels[current] Have_labeled.append(neighbor) queue_center.append(neighbor)
使用 BFS 扩展簇,将邻域点标记为相同标签
6. 统一标签编号
1 2 3 4 5 6
final_labels = np.unique(self.labels) label_map = {label: i for i, label in enumerate(final_labels)} if -1 in label_map: label_map[-1] = -1 self.labels = np.array([label_map[label] for label in self.labels])