首页 > 编程笔记 > Python笔记 阅读:21

K-Means聚类算法详解(附带实例)

聚类(clustering)是一种寻找数据之间内在结构的技术。聚类把全体数据实例组织成一些相似组,而这些相似组被称作簇。处于相同簇中的数据实例彼此相同,处于不同簇中的实例彼此不同。K-Means、AgglomerativeClustering、DBSCAN、MeanShift、SpectralClustering 等是常用的聚类方法。

K-Means 算法又名 K 均值算法,K-Means 算法中的 K 表示的是聚类为 K 个簇,Means 代表取每一个聚类中数据值的均值作为该簇的中心,或者称为质心,即用每一个类的质心对该簇进行描述。

K-Means算法原理

K-Means 算法是一种典型的基于划分的聚类算法,属于无监督学习算法。

K-Means 算法预先指定初始聚类数以及初始化聚类中心,按照样本之间的距离大小,把样本集根据数据对象与聚类中心之间的相似度划分为类簇,不断更新聚类中心的位置,不断降低类簇的误差平方和(Sum of Squared Error,SSE),当 SSE 不再变化或目标函数收敛时,聚类结束,得到最终结果。

K-Means 算法的核心思想是:
空间中数据对象与聚类中心间的欧氏距离计算公式为:


其中,X 为数据对象;Ci 为第 i 个聚类中心;m 为数据对象的维度;Xj、Cij 为 X 和 Ci 的第 j 个属性值。

整个数据集的 SSE 计算公式为:


其中,SSE 的大小表示聚类结果的好坏;k 为簇的个数。

K-Means算法步骤

K-Means 算法的实质是 EM 算法(Expectation-Maximization algorithm,最大期望算法)的模型优化过程,具体步骤如下:
  1. 随机选择 K 个样本作为初始簇类的均值向量。
  2. 将每个样本数据集划分离它距离最近的簇。
  3. 根据每个样本所属的簇,更新簇类的均值向量。
  4. 重复 2、3 步,当达到设置的迭代次数或簇类的均值向量不再改变时,模型构建完成,输出聚类算法结果。

K-Means算法的缺陷

K-Means算法非常简单且使用广泛,但是主要存在以下 4 个缺陷。

使用sklearn进行K-Means聚类

K-Means 算法实现非常容易,并且与其他聚类算法相比,它的计算效率也非常高,这是它受欢迎的原因。K-Means 算法属于基于原型的聚类类别。

基于原型的聚类即每个聚类都由一个原型表示,原型通常是具有连续特征的相似点的质心(平均值)。虽然 K-Means 算法非常擅长识别具有球形形状的聚类,但这种聚类算法的缺点是必须先验地指定聚类的数量 K。

肘法和轮廓图是评估聚类质量的有用技术,可帮助确定最佳聚类数K。

【实例】使用 sklearn 实现 K-Means 聚类。
from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt

# 支持中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# 生成数据
X, y = make_blobs(n_samples=150,
                  n_features=2,
                  centers=3,
                  cluster_std=0.5,
                  shuffle=True,
                  random_state=0)

# 绘制散点图
plt.scatter(X[:, 0],
            X[:, 1],
            c='white',
            marker='o',
            edgecolor='black',
            s=50)

plt.xlabel('特征1')
plt.ylabel('特征2')
plt.grid()
plt.tight_layout()
plt.show()
运行程序,数据集由 150 个随机生成的点大致分为 3 个密度较高的区域,通过二维散点图可视化如下图所示。


图 3 散点图

接下来,下一个问题是如何衡量对象之间的相似性。可以将相似度定义为距离的反义词,对具有连续特征的样本进行聚类的常用距离是点 x 和 y 之间的平方欧几里得距离。

在 m 维空间中,有:


式中,索引 j 指的是实例输入 x 和 y 的第 j 个维度(特征列)。其余部分将使用上标 i 和 j 分别表示实例(数据记录)的索引和集群索引。

接下来,使用 sklearn cluster 模块中的类将它应用到实例数据集:
from sklearn.cluster import KMeans

km = KMeans(n_clusters=3,
            init='random',
            n_init=10,
            max_iter=300,
            tol=1e-04,
            random_state=0)

y_km = km.fit_predict(X)
当使用欧几里得距离度量将 K-Means 应用于真实世界的数据时,要确保在相同的尺度上测量特征,并在必要时应用 Z-score 标准化或 Min-Max 缩放。

下面通过代码可视化 K-Means 算法在数据集中识别的集群以及集群质心。存储 cluster_centers_ 拟合 K-Means 对象的属性如下:
import matplotlib.pyplot as plt

plt.scatter(X[y_km == 0, 0],
            X[y_km == 0, 1],
            s=50, c='lightgreen',
            marker='s', edgecolor='black',
            label='聚类1')

plt.scatter(X[y_km == 1, 0],
            X[y_km == 1, 1],
            s=50, c='orange',
            marker='o', edgecolor='black',
            label='聚类2')

plt.scatter(X[y_km == 2, 0],
            X[y_km == 2, 1],
            s=50, c='lightblue',
            marker='v', edgecolor='black',
            label='聚类3')

plt.scatter(km.cluster_centers_[:, 0],
            km.cluster_centers_[:, 1],
            s=250, marker='*',
            c='red', edgecolor='black',
            label='质心')

plt.xlabel('特征1')
plt.ylabel('特征2')
plt.legend(scatterpoints=1)
plt.grid()
plt.tight_layout()
plt.show()
运行程序,效果如下图所示:


图 5 K-Means聚类效果

在图 5 中,可以看到 K-Means 将 3 个质心放在每个球体的中心。尽管 K-Means 在这个数据集上运行良好,但仍然存在必须先验地指定聚类数量 K 的缺点。

在实际应用中,要选择的集群数量可能并不总是那么明显,尤其是当使用无法可视化的高维数据集时。

相关文章