K-Means 算法 Python 实现:3 种可视化方案对比与 1 个完整动画代码

发布时间:2026/7/13 11:30:33

K-Means 算法 Python 实现:3 种可视化方案对比与 1 个完整动画代码 K-Means 算法 Python 实现3 种可视化方案对比与 1 个完整动画代码在数据科学领域K-Means 算法因其简洁高效而广受欢迎。但真正理解其迭代过程往往需要直观的可视化支持。本文将带你用 Python 实现三种不同的可视化方案并提供一个完整的动画演示代码让你不仅掌握算法原理还能生动展示聚类过程。1. 环境准备与数据加载首先确保你的 Python 环境已安装必要的库pip install numpy matplotlib scikit-learn我们使用经典的test.txt数据集进行演示。这个二维数据集包含 80 个样本点非常适合可视化展示import numpy as np from matplotlib import pyplot as plt from sklearn.datasets import make_blobs # 加载数据集 def load_data(file_path): data [] with open(file_path) as f: for line in f.readlines(): point list(map(float, line.strip().split())) data.append(point) return np.array(data) # 生成示例数据备选 def generate_sample_data(): X, _ make_blobs(n_samples300, centers4, cluster_std0.6) return X提示实际项目中建议先用sklearn.datasets.make_blobs生成可控的测试数据验证算法正确性后再应用于真实数据。2. 三种可视化方案实现2.1 静态分步图解法这种方案适合教学演示能清晰展示算法每个关键步骤def plot_steps(data, centers, assignments, step): plt.figure(figsize(10, 6)) colors [r, g, b, c, m, y, k] # 绘制数据点 for i in range(len(centers)): cluster_data data[assignments i] plt.scatter(cluster_data[:,0], cluster_data[:,1], ccolors[i], s50, alpha0.6) # 绘制中心点 plt.scatter(centers[:,0], centers[:,1], markerx, s200, ck, linewidths3) plt.title(fK-Means 第 {step} 步) plt.grid(True) plt.show()典型输出效果初始随机中心点第一次聚类结果中心点更新后状态最终收敛状态2.2 动态迭代动画使用 Matplotlib 的FuncAnimation实现流畅的迭代过程演示from matplotlib.animation import FuncAnimation class KMeansAnimator: def __init__(self, data, k4): self.data data self.k k self.fig, self.ax plt.subplots(figsize(10, 6)) self.colors plt.cm.rainbow(np.linspace(0, 1, k)) # 初始化中心点 self.centers data[np.random.choice(len(data), k, replaceFalse)] self.assignments np.zeros(len(data)) def update(self, frame): self.ax.clear() # 分配点到最近中心 distances np.sqrt(((self.data - self.centers[:, np.newaxis])**2).sum(axis2)) self.assignments np.argmin(distances, axis0) # 绘制聚类结果 for i in range(self.k): cluster_data self.data[self.assignments i] self.ax.scatter(cluster_data[:,0], cluster_data[:,1], colorself.colors[i], s50, alpha0.6) self.ax.scatter(self.centers[i,0], self.centers[i,1], markerx, s200, ck, linewidths3) # 更新中心点位置 new_centers np.array([self.data[self.assignments i].mean(axis0) for i in range(self.k)]) # 绘制中心点移动轨迹 for i in range(self.k): self.ax.plot([self.centers[i,0], new_centers[i,0]], [self.centers[i,1], new_centers[i,1]], k--, alpha0.3) self.centers new_centers self.ax.set_title(fK-Means 迭代 {frame1}) return self.ax # 使用示例 data load_data(test.txt) animator KMeansAnimator(data) animation FuncAnimation(animator.fig, animator.update, frames10, interval1000) plt.show()2.3 中心点轨迹图这种可视化专注于展示中心点的移动路径揭示算法收敛过程def plot_centroid_path(data, k4, max_iter10): centers_history [] centers data[np.random.choice(len(data), k, replaceFalse)] centers_history.append(centers.copy()) for _ in range(max_iter): # 分配点到最近中心 distances np.sqrt(((data - centers[:, np.newaxis])**2).sum(axis2)) assignments np.argmin(distances, axis0) # 更新中心点 new_centers np.array([data[assignments i].mean(axis0) for i in range(k)]) centers_history.append(new_centers.copy()) centers new_centers # 绘制轨迹 plt.figure(figsize(10, 6)) colors plt.cm.rainbow(np.linspace(0, 1, k)) for i in range(k): path np.array([step[i] for step in centers_history]) plt.plot(path[:,0], path[:,1], o-, ccolors[i], markersize8, linewidth2, labelf中心点 {i1}) plt.scatter(data[:,0], data[:,1], cgray, s30, alpha0.3) plt.title(K-Means 中心点移动轨迹) plt.legend() plt.grid(True) plt.show()3. 完整动画代码实现下面是一个可直接运行的完整 K-Means 动画实现包含交互式控件import numpy as np import matplotlib.pyplot as plt from matplotlib.animation import FuncAnimation from matplotlib.widgets import Slider, Button class InteractiveKMeans: def __init__(self, data, k4): self.data data self.k k self.fig, self.ax plt.subplots(figsize(10, 7)) plt.subplots_adjust(bottom0.25) # 初始化参数 self.centers data[np.random.choice(len(data), k, replaceFalse)] self.assignments np.zeros(len(data)) self.colors plt.cm.tab10(np.linspace(0, 1, k)) # 创建控件 ax_iter plt.axes([0.2, 0.1, 0.6, 0.03]) self.slider Slider(ax_iter, 迭代次数, 1, 20, valinit1, valstep1) ax_reset plt.axes([0.8, 0.025, 0.1, 0.04]) self.reset_btn Button(ax_reset, 重置, colorlightgoldenrodyellow) # 绑定事件 self.slider.on_changed(self.update) self.reset_btn.on_clicked(self.reset) self.animation FuncAnimation(self.fig, self.animate, frames20, interval500, repeat_delay2000) def reset(self, event): self.slider.reset() self.centers self.data[np.random.choice(len(self.data), self.k, replaceFalse)] self.update(0) def update(self, val): iterations int(self.slider.val) self.centers self.data[np.random.choice(len(self.data), self.k, replaceFalse)] for _ in range(iterations): distances np.sqrt(((self.data - self.centers[:, np.newaxis])**2).sum(axis2)) self.assignments np.argmin(distances, axis0) self.centers np.array([self.data[self.assignments i].mean(axis0) for i in range(self.k)]) self.draw_clusters() def animate(self, frame): distances np.sqrt(((self.data - self.centers[:, np.newaxis])**2).sum(axis2)) self.assignments np.argmin(distances, axis0) self.centers np.array([self.data[self.assignments i].mean(axis0) for i in range(self.k)]) self.draw_clusters() return self.ax def draw_clusters(self): self.ax.clear() for i in range(self.k): cluster_data self.data[self.assignments i] self.ax.scatter(cluster_data[:,0], cluster_data[:,1], colorself.colors[i], s50, alpha0.6) self.ax.scatter(self.centers[i,0], self.centers[i,1], markerx, s200, ck, linewidths3) self.ax.set_title(fK-Means 聚类 (k{self.k})) self.ax.grid(True) def show(self): plt.show() # 使用示例 data load_data(test.txt) visualizer InteractiveKMeans(data, k4) visualizer.show()4. 可视化方案对比与选型三种方案各有优劣下面是详细对比方案类型优点缺点适用场景静态分步图制作简单步骤清晰缺乏连续性需要手动切换教学演示、文档说明动态迭代动画直观展示迭代过程视觉效果好实现较复杂性能开销大现场演示、视频教程中心点轨迹图突出算法收敛特性丢失了数据点分配细节算法分析、参数调优在实际项目中我通常会根据需求组合使用这些技术。例如用静态图解释算法原理用动画展示实际运行过程最后用轨迹图分析算法收敛情况。

相关新闻