K-均值聚类算法详解
K-均值(K-Means)是机器学习中最经典、最常用的无监督学习聚类算法之一。它以其简洁性、高效性和直观性,成为数据挖掘、图像分割、推荐系统等多个领域的核心技术工具。本文将深入讲解K-均值的原理、实现步骤、数学推导以及实际应用场景。
1. 什么是K-均值聚类?
K-均值聚类是一种划分式聚类算法,其目标是将n个数据点划分为k个簇,使得每个数据点都属于离它最近的簇中心(质心),并最小化簇内样本到其质心的距离平方和。
核心思想
- 预先指定要划分的簇数 k
- 随机初始化k个质心
- 迭代优化:分配点→更新质心→重复直到收敛
2. 算法流程
2.1 标准K-均值算法步骤
# 伪代码表示
- 选择初始的 k 个质心 (c₁, c₂, ..., cₖ)
- 重复以下步骤直到收敛:
a. 将每个样本分配给最近的质心(基于欧氏距离)
b. 重新计算每个簇的质心(取簇内所有点的均值)
2.2 数学表达
设数据集为 $ X = \{x1, x2, ..., xn\} \subset \mathbb{R}^d $,要分成 $ k $ 个簇:$$
\min
$$
其中:
- $ Ci $ 是第i个簇
- $ \mui $ 是簇 $ Ci $ 的质心(均值向量)
- $ \|·\| $ 通常采用欧氏范数
3. 关键概念解析
3.1 距离度量
K-均值默认使用欧氏距离,但也可以根据数据类型选择其他距离函数:- 曼哈顿距离:适用于高维稀疏数据
- 余弦相似度:适用于文本向量化后的文档聚类
3.2 质心更新公式
当簇 $ Cj $ 包含 $ nj $ 个点时,其新质心为:$$
\mu
$$
3.3 停止条件
算法通常在以下情况停止:- 质心变化小于阈值 ε
- 达到最大迭代次数
- 簇分配不再改变
4. Python实战示例
import numpy as np
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
生成示例数据
np.random.seed(42)
X = np.random.randn(100, 2)
X[:50] += [3, 3] # 两个簇
执行K-均值聚类
kmeans = KMeans(nclusters=2, randomstate=42, ninit=10)
labels = kmeans.fitpredict(X)
可视化结果
plt.figure(figsize=(8,6)) plt.scatter(X[:,0], X[:,1], c=labels, cmap='viridis') centers = kmeans.clustercenters_ plt.scatter(centers[:,0], centers[:,1], marker='x', s=200, linewidths=3, color='r') plt.title('K-means Clustering Result') plt.show()5. 算法特性与局限性
✅ 优势
- 简单易懂:数学原理清晰,易于实现
- 高效快速:时间复杂度约为 O(nkd),适合大规模数据
- 可扩展性强:支持分布式计算和增量学习
❌ 缺点
- 需要预设k值:实际应用中难以确定最佳簇数
- 对异常值敏感:单个离群点可能显著影响质心位置
- 假设球形簇:要求簇呈凸形分布,不适用于复杂结构
- 对初始质心敏感:可能陷入局部最优解
6. 如何选择合适的k值?
6.1 肘部法则(Elbow Method)
计算不同k值对应的总簇内平方和(WCSS),寻找"拐点":wcss = []
for i in range(1, 11):
kmeans = KMeans(nclusters=i, randomstate=42)
kmeans.fit(X)
wcss.append(kmeans.inertia)
plt.plot(range(1,11), wcss, marker='o')
plt.xlabel('Number of clusters')
plt.ylabel('WCSS')
plt.title('Elbow Method')
plt.show()
6.2 轮廓系数(Silhouette Score)
评估聚类质量的指标,取值范围[-1,1],值越大越好:from sklearn.metrics import silhouettescore
silhouetteavg = silhouettescore(X, labels)
print(f"Silhouette Score: {silhouetteavg:.3f}")
7. 实际应用案例
7.1 客户分群
电商公司通过用户购买行为数据进行市场细分,制定差异化营销策略。7.2 图像压缩
将像素颜色聚类为有限种颜色,减少图像文件大小:from sklearn.cluster import MiniBatchKMeans
from PIL import Image
加载图像并转换为RGB数组
img = Image.open('image.jpg').convert('RGB')
pixels = np.array(img).reshape(-1, 3)
使用MiniBatchKMeans处理大数据量
kmeans = MiniBatchKMeans(nclusters=16, batchsize=1000)
labels = kmeans.fitpredict(pixels)
用聚类中心颜色替换原始像素
compressedpixels = kmeans.clustercenters[labels]
compressedimg = Image.fromarray(compressedpixels.reshape(img.size[1], img.size[0], 3))
compressedimg.save('compressedimage.jpg')
7.3 文档分类
在搜索引擎中,将网页内容自动归类到不同主题类别。8. 改进与变种算法
| 算法名称 | 主要改进 |
|---------|--------|
| K-Medoids | 使用实际数据点作为质心,抗噪声能力更强 |
| ISODATA | 动态调整簇数和大小,合并/分裂簇 |
| Fuzzy C-Means | 软聚类,允许点属于多个簇 |
| GMM | 基于概率模型,可处理非球形簇 |
9. 总结与建议
K-均值作为入门级聚类算法,具有以下特点:
- 适用场景:数据呈球形分布、簇大小相近、需要快速聚类
- 注意事项:
- 多次运行取最优结果(sklearn默认执行ninit次)
- 结合领域知识验证聚类结果合理性
虽然现代深度学习方法在某些任务上表现更优,但K-均值因其计算效率和可解释性,仍然是工业界不可或缺的基础工具。掌握K-均值不仅有助于理解聚类本质,更为后续学习更复杂的聚类算法打下坚实基础。