Bootstrap

【人工智能-初级】第7章 聚类算法K-Means:理论讲解与代码示例

一、K-Means聚类简介

K-Means 是一种广泛使用的无监督学习算法,主要用于数据聚类任务。它的目标是将数据集中的样本分为多个簇(Cluster),使得每个簇内的样本尽可能相似,而不同簇之间的样本尽可能不同。K-Means 非常适合探索性数据分析,可以帮助我们发现数据中的隐藏模式。

在 K-Means 中,“K” 表示预先设定的簇的数量,算法的目标是最小化各样本到其所属簇中心的距离之和。K-Means 算法被广泛用于客户分类、图像分割、市场分析等领域。

二、K-Means 聚类的工作原理

K-Means 算法的基本思想是通过迭代地更新簇中心和样本的簇分配,找到使得簇内样本相似度最大、簇间样本相似度最小的分组方案。具体地,K-Means 聚类的工作过程可以分为以下几个步骤:

2.1 初始化簇中心

首先随机选择 K 个数据点作为初始簇中心(Centroids),这些中心点将作为初始的簇的代表。

2.2 分配簇标签

对于每个数据点,计算它到所有簇中心的距离(通常使用欧氏距离),并将其分配给最近的簇中心。

2.3 更新簇中心

重新计算每个簇的中心,将簇内所有数据点的均值作为新的簇中心。

2.4 迭代重复

重复步骤 2 和步骤 3,直至簇中心不再变化或者达到最大迭代次数为止。最终的簇中心和簇分配就是算法的输出结果。

2.5 K-Means 算法的目标

K-Means 算法的目标是最小化所有数据点到其所属簇中心的距离之和,通常称为“簇内误差平方和”(Within-Cluster Sum of Squares,简称 WCSS):

W C S S = ∑ i = 1 K ∑ x ∈ C i ∣ ∣ x − μ i ∣ ∣ 2 WCSS = \sum_{i=1}^{K} \sum_{x \in C_i} ||x - \mu_i||^2 WCSS=i=1KxCi∣∣xμi2

其中,K 是簇的数量,C_i 是第 i 个簇,\mu_i 是第 i 个簇的中心,||x - \mu_i|| 表示数据点 x 到簇中心的距离。

三、K-Means 聚类的优缺点

3.1 优点

  1. 简单易理解:K-Means 算法的原理非常简单,容易实现和理解。
  2. 计算速度快:在中小规模数据上,K-Means 算法的计算速度非常快,适用于大多数的聚类场景。
  3. 适应性广:K-Means 可用于多种类型的数据,包括图像、文本等。

3.2 缺点

  1. 需要预先设定簇的数量 K:K-Means 算法要求事先指定簇的数量,实际中选择合适的 K 值可能需要多次尝试。
  2. 对初始值敏感:K-Means 聚类的结果对初始簇中心的选择敏感,容易陷入局部最优解。使用 K-Means++ 算法可以有效改善这一问题。
  3. 不适合非球形数据:K-Means 假设每个簇是球形的,这在某些情况下可能不适用,如复杂形状的簇或簇的大小相差较大。

四、K 值的选择

如何选择合适的 K 值是 K-Means 聚类中的一个重要问题。常用的方法有:

  1. 肘部法则(Elbow Method):通过绘制不同 K 值对应的簇内误差平方和(WCSS),找到“肘部点”,即误差下降速度变慢的地方。

  2. 轮廓系数(Silhouette Coefficient):用于评估不同 K 值下聚类的质量,轮廓系数值越大,表示聚类效果越好。

五、Python 实现 K-Means 聚类

接下来,我们使用 Python 来实现一个简单的 K-Means 聚类,使用 scikit-learn 库来帮助我们完成这一任务。

5.1 导入必要的库

首先,我们需要导入一些必要的库:

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
  • numpy:用于数值计算。
  • matplotlib:用于数据可视化。
  • sklearn.datasets:用于生成模拟数据集。
  • KMeans:用于创建 K-Means 聚类模型。
  • silhouette_score:用于计算聚类结果的轮廓系数。

5.2 生成数据集并进行可视化

我们使用 make_blobs 函数生成一个简单的二维数据集,以便更好地可视化聚类结果。

# 生成数据集
X, y = make_blobs(n_samples=300, centers=4, cluster_std=1.0, random_state=42)

# 可视化数据集
plt.scatter(X[:, 0], X[:, 1], s=50, cmap='viridis')
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.title('Generated Dataset')
plt.show()
  • make_blobs:生成模拟数据集,n_samples=300 表示样本数量,centers=4 表示簇的数量。
  • plt.scatter:绘制散点图,用于可视化数据集。

5.3 创建 K-Means 聚类模型并进行训练

我们创建一个 K-Means 模型,并用数据集进行聚类。

# 创建 K-Means 模型
kmeans = KMeans(n_clusters=4, random_state=42)

# 训练模型
kmeans.fit(X)

# 获取簇中心和簇标签
centroids = kmeans.cluster_centers_
labels = kmeans.labels_
  • KMeans(n_clusters=4):创建 K-Means 聚类模型,指定簇的数量为 4。
  • kmeans.fit(X):使用数据集进行模型训练。
  • cluster_centers_:获取每个簇的中心。
  • labels_:获取每个样本的簇标签。

5.4 可视化聚类结果

我们可以将聚类结果可视化,包括每个数据点的簇分配以及簇中心的位置。

# 绘制聚类结果
plt.scatter(X[:, 0], X[:, 1], c=labels, s=50, cmap='viridis')
plt.scatter(centroids[:, 0], centroids[:, 1], c='red', s=200, alpha=0.75, marker='x')
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.title('K-Means Clustering Result')
plt.show()
  • plt.scatter:绘制聚类结果,使用不同的颜色表示不同的簇,红色的叉表示簇中心。

5.5 选择最佳 K 值——肘部法则

接下来,我们通过肘部法则来选择最佳的 K 值。

# 计算不同 K 值下的簇内误差平方和
wcss = []
k_values = range(1, 11)

for k in k_values:
    kmeans = KMeans(n_clusters=k, random_state=42)
    kmeans.fit(X)
    wcss.append(kmeans.inertia_)

# 绘制肘部法则图
plt.plot(k_values, wcss, marker='o')
plt.xlabel('Number of Clusters (K)')
plt.ylabel('Within-Cluster Sum of Squares (WCSS)')
plt.title('Elbow Method for Optimal K')
plt.show()
  • inertia_:K-Means 模型的 inertia_ 属性表示簇内误差平方和(WCSS)。
  • plt.plot:绘制不同 K 值下的 WCSS,以便找到肘部点。

5.6 使用轮廓系数评估聚类质量

我们还可以使用轮廓系数来评估不同 K 值下的聚类质量。

# 计算不同 K 值下的轮廓系数
silhouette_scores = []

for k in range(2, 11):
    kmeans = KMeans(n_clusters=k, random_state=42)
    labels = kmeans.fit_predict(X)
    silhouette_scores.append(silhouette_score(X, labels))

# 绘制轮廓系数图
plt.plot(range(2, 11), silhouette_scores, marker='o')
plt.xlabel('Number of Clusters (K)')
plt.ylabel('Silhouette Score')
plt.title('Silhouette Score for Different K Values')
plt.show()
  • fit_predict:对数据进行聚类并返回每个样本的簇标签。
  • silhouette_score:用于计算聚类结果的轮廓系数,轮廓系数越高,表示聚类效果越好。

六、总结

K-Means 是一种简单而有效的聚类算法,适用于中小规模的数据聚类任务。它通过迭代更新簇中心和样本分配,最终找到使簇内相似度最大、簇间相似度最小的分组方案。K-Means 算法的优点在于简单易理解、计算速度快,但也存在一些缺点,如对簇数量 K 的选择敏感、容易陷入局部最优解等。

6.1 学习要点

  1. K-Means 原理:通过迭代更新簇中心和分配样本来找到最佳的聚类方案。
  2. K 值的选择:可以通过肘部法则和轮廓系数来选择最佳的 K 值。
  3. Python 实现:可以使用 scikit-learn 库中的 KMeans 轻松实现 K-Means 聚类。

6.2 练习题

  1. 使用 K-Means 对 Iris 数据集进行聚类,观察不同 K 值对聚类结果的影响。
  2. 尝试使用不同的初始簇中心选择方法(如 K-Means++)来进行聚类,比较结果的不同。
  3. 使用 make_moons 数据集进行聚类,观察 K-Means 对非球形数据的聚类效果。

希望本文能帮助您更好地理解 K-Means 聚类的基本概念和实现方法。下一篇文章将为您介绍朴素贝叶斯分类及其 Python 实现。如果有任何问题,欢迎在评论中讨论!

;