[机器学习]kmeans++聚类

502 阅读3分钟

K-Means 算法详解

简单高效, 时间复杂度低, 容易解释

适用于大数据量的集合, 但是特征维度不要太高

指定k值(簇的数量), 随机选择初始聚类中心

只能处理凸形簇,不能处理非凸形簇(比如环形数据集)

一、算法逻辑

K-Means 是一种无监督聚类算法,核心目标是将数据集划分为 K 个簇,使得同一簇内的数据点相似度高,不同簇间的数据点相似度低。其流程如下:

  1. 初始化中心点

    • 随机选择 K 个数据点作为初始聚类中心(质心)。
  2. 迭代优化

    • 分配步骤:将每个数据点分配到距离最近的质心对应的簇。
    • 更新步骤:重新计算每个簇的质心(取簇内所有点的均值,这个时候计算出来的新的质心可能不是簇内的一个真实的数据点)。
    • 重复上述步骤,直到质心不再显著变化(或达到最大迭代次数)。
  3. 终止条件

    • 质心变化小于阈值,或达到预设的最大迭代次数。
# 伪代码示例
初始化 K 个质心
while 未收敛:
    将每个点分配到最近的质心对应的簇
    重新计算每个簇的质心

二、优缺点分析

优点缺点
1. 简单高效,时间复杂度低(O(NKT))1. 需预先指定 K 值,选择不当可能导致效果差
2. 适用于大数据集2. 对初始质心敏感,可能收敛到局部最优
3. 结果易于解释3. 对噪声和异常值敏感(可用 K-Medoids 改进)
4. 只能处理凸形簇,对非凸簇效果差(如环形数据)

三、适用场景

  1. 数据分布均匀,簇形状接近球形。
  2. 数据量较大但特征维度不高。
  3. 典型应用:客户分群、图像分割、文档分类、异常检测。

四、K-Means++ 算法的改进

核心改进:优化初始质心的选择,减少算法对初始化的依赖。

步骤

  1. 随机选择第一个质心。
  2. 后续质心的选择概率与当前点到最近质心的距离平方成正比(距离越远,概率越高)。
  3. 重复直到选出 K 个质心。

优势

  • 初始质心更分散,覆盖不同簇。
  • 减少迭代次数,提高收敛速度和稳定性。
  • 在多数情况下,聚类效果优于原始 K-Means。

完整 Python 代码示例

import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs

# 生成模拟数据
X, y = make_blobs(n_samples=500, centers=3, cluster_std=0.8, random_state=42)

# K-Means++ 聚类
kmeans_pp = KMeans(n_clusters=3, init='k-means++', n_init=10, random_state=42)
kmeans_pp.fit(X)
labels_pp = kmeans_pp.labels_
centers_pp = kmeans_pp.cluster_centers_

# 原始 K-Means 对比(随机初始化)
kmeans = KMeans(n_clusters=3, init='random', n_init=1, random_state=42)
kmeans.fit(X)
labels = kmeans.labels_
centers = kmeans.cluster_centers_

# 可视化结果
plt.figure(figsize=(12, 5))

# K-Means++
plt.subplot(1, 2, 1)
plt.scatter(X[:, 0], X[:, 1], c=labels_pp, cmap='viridis', s=50, alpha=0.6)
plt.scatter(centers_pp[:, 0], centers_pp[:, 1], c='red', s=200, marker='X')
plt.title("K-Means++")

# 原始 K-Means
plt.subplot(1, 2, 2)
plt.scatter(X[:, 0], X[:, 1], c=labels, cmap='viridis', s=50, alpha=0.6)
plt.scatter(centers[:, 0], centers[:, 1], c='red', s=200, marker='X')
plt.title("K-Means (Random Init)")

plt.show()

代码说明

  1. 数据生成:使用 make_blobs 生成 3 个高斯分布的簇。
  2. 模型训练:分别使用 K-Means++ 和随机初始化的 K-Means。
  3. 可视化:对比两种初始化方法的聚类效果,红色叉号表示质心位置。

输出效果

  • K-Means++ 的质心通常更准确地分布在簇中心。
  • 随机初始化的 K-Means 可能因初始质心不佳导致次优聚类。

总结

  • K-Means 简单高效,但对初始化和噪声敏感。
  • K-Means++ 通过优化初始化显著提升稳定性,是实际应用中的推荐方法。
  • 在 Scikit-Learn 中,KMeans 默认使用 K-Means++ 初始化(init='k-means++')。