K 均值聚类:从概念到实践的无监督学习之旅
在机器学习的世界里,有一类算法能在没有 “参考答案”(标签)的情况下,将相似的数据自动归为一类,这就是聚类算法。其中,K 均值(K-means)算法因其简单高效,成为最常用的聚类方法之一。
一、聚类:无监督学习的 “分组术”
聚类是机器学习中的一种无监督学习任务 —— 也就是说,我们手上的数据没有预设的标签(比如 “猫”“狗” 或 “好”“坏”),需要通过算法自动发现数据中的内在结构,将相似的样本分到同一组(称为 “簇”),不同的样本分到不同的组。
举个例子:如果给你一组包含身高、体重的数据,聚类算法能自动将 “高瘦”“矮胖” 等特征相似的人归为一类,而不需要提前告诉你 “这是高瘦组”。
聚类的核心挑战在于两点:
- 如何定义 “相似”(通常通过距离度量);
- 如何评估聚类结果的好坏(因为没有标签,无法直接判断对错)。
二、衡量 “相似性”:距离度量的关键作用
要判断两个样本是否相似,最直观的方式是计算它们之间的 “距离”—— 距离越近,越相似。常用的距离度量有两种:
1. 欧式距离(欧几里得距离)
这是我们最熟悉的距离度量,本质是多维空间中两点之间的 “直线距离”。
2. 曼哈顿距离(出租车距离)
想象在城市网格中,出租车从一个点到另一个点的行驶距离(只能沿直角方向移动),就是曼哈顿距离。
三、K 均值聚类:算法步骤详解
K 均值聚类的核心思想是:通过迭代找到\(k\)个簇的中心,让每个样本都属于离它最近的中心所在的簇,最终使簇内样本尽可能相似,簇间样本尽可能不同。
具体步骤如下:
- 初始化:随机选择\(k\)个样本作为初始的 “簇中心”(k是我们需要提前设定的簇数量);
- 分配样本:计算每个样本到\(k\)个簇中心的距离,将样本分到距离最近的簇中;
- 更新中心:对每个簇,计算簇内所有样本的均值(如均值坐标),作为新的簇中心;
- 迭代收敛:重复步骤 2 和 3,直到簇中心不再明显变化(或达到最大迭代次数),此时的聚类结果即为最终结果。
四、如何评估聚类效果?CH 指标
由于聚类是无监督学习,没有标签来直接验证结果,我们需要通过 “内部指标” 评估。其中,CH 指标(Calinski-Harabasz 指数)是常用的一种:
- 类内紧密度:计算每个样本与所在簇中心的距离平方和,值越小说明簇内样本越集中;
- 类间分离度:计算各簇中心与整个数据集中心的距离平方和,值越大说明簇与簇之间越分散。
CH 指标的计算公式为 “类间分离度 / 类内紧密度” 的比值,CH 值越大,说明聚类结果越好(簇内越密,簇间越散)。
五、K 均值的优缺点
优点:
- 简单直观,容易理解和实现;
- 计算效率高,时间复杂度与样本数量呈线性关系,适合处理大规模常规数据集。
缺点:
- k 值难确定:需要人工预设\(k\),而实际数据中最优\(k\)往往未知;
- 对初始簇中心敏感:不同的初始中心可能导致不同的聚类结果;
- 难以处理复杂形状的簇:比如环形、非凸形数据,容易分错。
六、代码实践:用 Python 实现 K 均值聚类
我们可以用scikit-learn库快速实现 K 均值聚类,步骤如下:
1. 生成模拟数据
用make_blobs函数生成适合聚类的数据集,关键参数:
- n_samples:样本数量(默认 100);
- n_features:样本维度(默认 2);
- centers:簇的数量(默认 3);
- random_state:随机种子(固定结果)。
from sklearn.datasets import make_blobs
# 生成3个簇,100个样本,2个特征
X, y_true = make_blobs(n_samples=100, n_features=2, centers=3, random_state=42)
2. 应用 K 均值算法
用KMeans类进行聚类,关键参数:
- n_clusters:簇的数量(即\(k\));
- max_iter:最大迭代次数;
- random_state:随机种子。
from sklearn.cluster import KMeans
# 设定k=3,训练模型
kmeans = KMeans(n_clusters=3, random_state=42)
y_pred = kmeans.fit_predict(X)
3. 可视化结果(可选)
用matplotlib绘制聚类结果,不同簇用不同颜色标记:
import matplotlib.pyplot as plt
plt.scatter(X[:, 0], X[:, 1], c=y_pred, cmap='viridis')
plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1], s=300, c='red', label='中心')
plt.legend()
plt.show()
总结
K 均值聚类作为一种经典的无监督学习算法,凭借简单高效的特点,在客户分群、图像分割、异常检测等场景中被广泛应用。但它也有局限性,实际使用时需要结合数据特点选择合适的距离度量和k值