文章目录
一、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=1∑Kx∈Ci∑∣∣x−μi∣∣2
其中,K 是簇的数量,C_i 是第 i 个簇,\mu_i 是第 i 个簇的中心,||x - \mu_i|| 表示数据点 x 到簇中心的距离。
三、K-Means 聚类的优缺点
3.1 优点
- 简单易理解:K-Means 算法的原理非常简单,容易实现和理解。
- 计算速度快:在中小规模数据上,K-Means 算法的计算速度非常快,适用于大多数的聚类场景。
- 适应性广:K-Means 可用于多种类型的数据,包括图像、文本等。
3.2 缺点
- 需要预先设定簇的数量 K:K-Means 算法要求事先指定簇的数量,实际中选择合适的 K 值可能需要多次尝试。
- 对初始值敏感:K-Means 聚类的结果对初始簇中心的选择敏感,容易陷入局部最优解。使用 K-Means++ 算法可以有效改善这一问题。
- 不适合非球形数据:K-Means 假设每个簇是球形的,这在某些情况下可能不适用,如复杂形状的簇或簇的大小相差较大。
四、K 值的选择
如何选择合适的 K 值是 K-Means 聚类中的一个重要问题。常用的方法有:
-
肘部法则(Elbow Method):通过绘制不同 K 值对应的簇内误差平方和(WCSS),找到“肘部点”,即误差下降速度变慢的地方。
-
轮廓系数(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 学习要点
- K-Means 原理:通过迭代更新簇中心和分配样本来找到最佳的聚类方案。
- K 值的选择:可以通过肘部法则和轮廓系数来选择最佳的 K 值。
- Python 实现:可以使用 scikit-learn 库中的 KMeans 轻松实现 K-Means 聚类。
6.2 练习题
- 使用 K-Means 对 Iris 数据集进行聚类,观察不同 K 值对聚类结果的影响。
- 尝试使用不同的初始簇中心选择方法(如 K-Means++)来进行聚类,比较结果的不同。
- 使用 make_moons 数据集进行聚类,观察 K-Means 对非球形数据的聚类效果。
希望本文能帮助您更好地理解 K-Means 聚类的基本概念和实现方法。下一篇文章将为您介绍朴素贝叶斯分类及其 Python 实现。如果有任何问题,欢迎在评论中讨论!