“聚类”(Clustering)试图将数据集中的样本划分为若干个不相交的子集,每个子集被称为一个“簇”或者“类”,英文名为Cluster。比如鸢尾花数据集(Iris Dataset)中有多个不同的子品种:Setosa、Versicolor、Virginica,不同品种的一些观测数据是具有明显差异的,我们希望根据这些观测数据将其进行聚类。
下图可以看到,不同品种的鸢尾花的花萼(Sepal)和花瓣(Petal)长度和宽度存在明显的差异。花萼长度(Sepal Length)、花萼宽度(Sepal Width)等观测数据可以作为样本的特征,用来进行聚类分析。
不同鸢尾花的花萼长度和宽度不同
形式化地说,一个样本集D包含m个样本,每个样本有n维特征,聚类算法根据n维特征数据中的一些潜在数据分布,将样本集D分为k个不相交的簇。需要注意的是:聚类过程是机器算法自动确定分类的过程,机器所确定的分类与真实分类之间的语义联系需要使用者把握。总之,聚类是一种非监督学习(Unsupervised Learning),我们可以不用事先确定一个样本到底分到哪一类,机器会从样本的特征数据中发现一些潜在模式,最终将相似样本归结到一起。
K-Means算法
K均值(K-Means)算法是最常用的聚类算法。
K-Means算法的伪代码 来源:周志华《机器学习》
上图为周志华老师《机器学习》一书给出的伪代码,用数学语言表示这个算法,看起来有些缭乱,但其算法思想很简单。假如我们想把数据集D划分为K个簇,大致需要以下几步:
- 在数据集D中随机选择K个点,这K个点表示K个簇的中心点,即伪代码第1行。
- 计算数据集D中各个数据应该被分到哪些簇:具体而言,计算样本中所有点距离这K个中心点的距离,将某个样本x划分到距离其最近的中心点对应的簇上,如伪代码的4-8行。
- 优化当前的聚类结构:对于刚刚生成的分类簇,重新计算簇的中心点,如伪代码的9-16行。
- 重复前面两步,直到我们得到一个满意的结果。
K-Means算法是一种采用贪心思想的迭代算法。下图展示了从初始状态开始进行的4次迭代,每次迭代,簇的中心点和簇内数据点也在变化。
将数据集分为3个簇,四轮迭代的结果,样本点为“·”,簇中心点为“ ” 来源:周志华《机器学习》
使用scikit-learn对Iris数据集进行聚类
Iris数据集共有3种类别的鸢尾花,每种50个样本。数据集提供了4个特征:花萼长度(Sepal Length)、花萼宽度(Sepal Width)、花瓣长度(Petal Length)和花瓣宽度(Petal Width)。
加载必要的库和数据集,对数据集进行简单探索。
代码语言:javascript复制
打印结果为:
代码语言:javascript复制
对花萼长度和宽度这两维数据进行可视化:
代码语言:javascript复制
花萼长度和宽度散点图可视化
代码语言:javascript复制
PCA 3D数据分布
通过图表中可以看到:数据集共有三个品种,不同品种的特征分布有一定的模式。
使用K-Means算法进行聚类分析
代码语言:javascript复制
数据集被分为3个簇,这三个簇的中心点坐标为:
代码语言:javascript复制
我们可以比较一下K-Means聚类结果和实际样本之间的差别:
代码语言:javascript复制
K-Means聚类后,聚类结果和实际样本之间的差别图
左侧是实际情况,右侧是聚类结果,实际结果中橘黄色和灰色类别的两种鸢尾花的数据表现上有一些交叉,聚类算法无法智能到将这些交叉在一起的点区分开来。