深入理解并实现基于Python的K-Means聚类算法

昨天 8阅读

在数据挖掘和机器学习领域,聚类是一种常见的无监督学习技术。它通过将数据点分组为若干个簇(clusters),使得同一簇内的数据点彼此相似,而不同簇的数据点差异较大。K-Means是其中最经典、最常用的聚类算法之一。本文将从理论基础出发,深入剖析K-Means算法的工作原理,并结合Python代码实现一个完整的K-Means聚类过程。


K-Means算法的基本原理

K-Means是一种基于距离的聚类算法,其目标是最小化簇内数据点到簇中心的距离平方和。具体来说,K-Means算法包含以下几个步骤:

初始化:随机选择K个点作为初始簇中心(centroids)。分配:将每个数据点分配到离它最近的簇中心。更新:重新计算每个簇的中心位置(即簇内所有点的均值)。迭代:重复执行分配和更新步骤,直到簇中心不再发生显著变化或达到最大迭代次数。

K-Means的核心思想是通过不断优化簇中心的位置,使数据点尽可能地靠近所属簇的中心。


K-Means算法的优缺点

优点

简单高效:K-Means算法易于理解和实现,计算复杂度较低,适合处理大规模数据集。可扩展性强:能够快速扩展到多维数据场景。结果直观:最终生成的簇具有清晰的几何结构。

缺点

对初始值敏感:不同的初始簇中心可能导致不同的聚类结果。依赖于K值:需要预先指定簇的数量K,但实际应用中K值的选择可能并不明确。不适用于非凸形状:K-Means假设簇是球形分布的,对于非凸形状的簇效果较差。

K-Means算法的Python实现

接下来,我们将使用Python从零开始实现K-Means算法,并通过一个简单的例子展示其运行过程。

1. 导入必要的库

import numpy as npimport matplotlib.pyplot as pltfrom sklearn.datasets import make_blobs
numpy:用于数值计算。matplotlib:用于可视化结果。sklearn.datasets.make_blobs:生成模拟数据集。

2. 数据生成

为了便于测试,我们使用make_blobs生成一个二维数据集,包含4个簇。

# 生成数据X, _ = make_blobs(n_samples=300, centers=4, cluster_std=0.60, random_state=0)# 可视化原始数据plt.scatter(X[:, 0], X[:, 1], s=50)plt.title("Original Data")plt.show()

运行上述代码后,可以看到生成的二维数据点分布如下图所示(实际生成结果可能略有不同)。

原始数据

3. K-Means算法实现

以下是K-Means算法的具体实现代码:

class KMeans:    def __init__(self, k=4, max_iters=100, tol=1e-4):        """        初始化K-Means参数        :param k: 簇的数量        :param max_iters: 最大迭代次数        :param tol: 收敛阈值        """        self.k = k        self.max_iters = max_iters        self.tol = tol        self.centroids = None        self.labels = None    def initialize_centroids(self, X):        """随机选择k个点作为初始簇中心"""        idx = np.random.choice(X.shape[0], self.k, replace=False)        return X[idx]    def assign_clusters(self, X):        """根据当前簇中心分配数据点"""        distances = np.linalg.norm(X[:, np.newaxis] - self.centroids, axis=2)        return np.argmin(distances, axis=1)    def update_centroids(self, X):        """根据分配结果更新簇中心"""        new_centroids = np.array([X[self.labels == i].mean(axis=0) for i in range(self.k)])        return new_centroids    def fit(self, X):        """训练模型"""        self.centroids = self.initialize_centroids(X)        for i in range(self.max_iters):            old_centroids = self.centroids.copy()            self.labels = self.assign_clusters(X)            self.centroids = self.update_centroids(X)            # 检查是否收敛            if np.all(np.abs(self.centroids - old_centroids) < self.tol):                print(f"Converged after {i + 1} iterations.")                break    def predict(self, X):        """预测新数据点的簇标签"""        return self.assign_clusters(X)

4. 使用K-Means进行聚类

接下来,我们使用上述实现的K-Means算法对生成的数据进行聚类。

# 创建KMeans实例并训练kmeans = KMeans(k=4)kmeans.fit(X)# 可视化聚类结果colors = ['r', 'g', 'b', 'y']for i in range(kmeans.k):    points = X[kmeans.labels == i]    plt.scatter(points[:, 0], points[:, 1], s=50, c=colors[i], label=f'Cluster {i}')# 绘制簇中心plt.scatter(kmeans.centroids[:, 0], kmeans.centroids[:, 1], s=200, c='black', marker='X', label='Centroids')plt.legend()plt.title("K-Means Clustering Result")plt.show()

运行后,可以看到聚类结果如下图所示:

聚类结果


改进与扩展

尽管K-Means算法简单高效,但在实际应用中仍存在一些局限性。以下是一些可能的改进方向:

K值选择:可以使用肘部法(Elbow Method)或轮廓系数(Silhouette Score)来确定最佳的K值。初始中心优化:采用K-Means++方法选择初始簇中心,以减少对随机性的依赖。非凸形状支持:结合DBSCAN等其他聚类算法,处理复杂的簇形状。高维数据处理:对于高维数据,可以先进行降维(如PCA)再进行聚类。

总结

本文详细介绍了K-Means聚类算法的基本原理,并通过Python代码实现了该算法的核心逻辑。通过对生成的二维数据集进行聚类,展示了K-Means的实际应用效果。同时,我们也讨论了K-Means的优缺点及潜在的改进方向。希望本文能为读者提供一个清晰的技术视角,并激发进一步探索的兴趣。

在未来的工作中,可以尝试将K-Means与其他算法结合,应用于更复杂的实际问题,例如图像分割、推荐系统等领域。

免责声明:本文来自网站作者,不代表CIUIC的观点和立场,本站所发布的一切资源仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。客服邮箱:ciuic@ciuic.com

目录[+]

您是本站第1915名访客 今日有9篇新文章

微信号复制成功

打开微信,点击右上角"+"号,添加朋友,粘贴微信号,搜索即可!