k-means聚类算法(上)
引用文章:【机器学习】K-means(非常详细) - 知乎 (zhihu.com)
(65条消息) 【机器学习】k-means聚类原理及python实现_大姨妈V的博客-CSDN博客_python实现kmeans聚类
K-Means优化——K-Means++,二分Kmeans - 知乎 (zhihu.com)
本文大致思路:1)先介绍经典模型牧师-村民,引入k-means算法
2)介绍算法步骤
3)每一步骤详解
4)伪代码和算法时间复杂度
5)收敛性证明
6)k-means算法优缺点及改进方法
一、牧师—村民模型
有四个牧师去郊区布道,一开始牧师们随意选了几个布道点,并且把这几个布道点的情况公告给了郊区所有的村民,于是每个村民到离自己家最近的布道点去听课。听课之后,大家觉得距离太远了,于是每个牧师统计了一下自己的课上所有的村民的地址,搬到了所有地址的中心地带,并且在海报上更新了自己的布道点的位置。牧师每一次移动不可能离所有人都更近,有的人发现A牧师移动以后自己还不如去B牧师处听课更近,于是每个村民又去了离自己最近的布道点……就这样,牧师每个礼拜更新自己的位置,村民根据自己的情况选择布道点,最终稳定了下来。该牧师的目的是为了让每个村民到其最近中心点的距离和最小。
二、算法步骤
1.随机确定k个初始点作为质心;
2.然后将数据集中的每个点分配到一个簇中,具体来讲,为每个点找距离其最近的质心,并将其分配给该质心所对应的簇;
3.每个簇的质心更新为该簇所有点的平均值;
4.重复2、3两步操作,直到达到某个终止条件。
三、步骤详解
1.K值的选择
k 的选择一般是按照实际需求进行决定,或在实现算法时直接给定 k 值。
注:(1)质心数量由用户给出,记为k,k-means最终得到的簇数量也是k,一个质心对应一个簇,每个样本只聚类到一个簇里面;
(2)后来每次更新的质心的个数都和初始k值相等;
(3)初始簇为空
2.距离度量
(1)在欧式空间中采用的是欧氏距离;
(2)在处理文档中采用的是余弦相似度函数;
(3)有时候也采用曼哈顿距离作为度量,不同的情况实用的度量公式是不同的。
已知:距离度量函数dist( , ),需满足一些性质
(1)非负性:![]()
(2)同一性:![]()
(3)对称性:![]()
(4)直递性:![]()
2.1欧氏距离

2.2曼哈顿距离

2.3余弦相似度

注:经过该步骤,得到k个新的簇,每个样本都会被分到k个簇中的某一个簇。
3.新质心的计算
对于分类后的产生的k个簇,分别计算到簇内其他点距离均值最小的点作为质心;
对于拥有坐标的簇可以计算每个簇坐标的均值作为质心;
注:经过该步骤,会得到k个新的质心,作为第二步中使用的质心。
4.终止条件
(1)质心不再改变
(2)loop至最大次数loopLimit
注:(当每个簇的质心,不再改变时就可以停止k-menas) or (当loop次数超过looLimit时,停止k-means)
如果这一步没有结束k-means,就再执行第二步、第三步、第四步
如果这一步结束了k-means,则就打印(或绘制)簇以及质心
四、伪代码和时空复杂度
1.伪代码
获取数据 n 个 m 维的数据 随机生成 K 个 m 维的点 while(t) for(int i=0;i < n;i++) for(int j=0;j < k;j++) 计算点 i 到类 j 的距离 for(int i=0;i < k;i++) 1. 找出所有属于自己这一类的所有数据点2.时空复杂度
已知t 为迭代次数,k 为簇的数目,n 为样本点数,m 为样本点维度
时间复杂度:O(tnkm)
空间复杂度:O(m(n+k))
五、收敛性证明
k-means的目标就是最小化各个类别中点到中心点的距离
损失函数:

其中:

求极值:

其中k 是指第 k 个中心点,可得:

EM 算法的缺点就是,容易陷入局部极小值,这也是 K-means 有时会得到局部最优解的原因。
六、算法优缺点及改进方法
1.优缺点
(1)优点
- 容易理解,聚类效果不错,虽然是局部最优, 但往往局部最优就够了;
- 处理大数据集的时候,该算法可以保证较好的伸缩性;
- 当簇近似高斯分布的时候,效果非常不错;
- 算法复杂度低。
(2)缺点
- K 值需要人为设定,不同 K 值得到的结果不一样;
- 对初始的簇中心敏感,不同选取方式会得到不同结果;
- 对异常值敏感;
- 样本只能归为一类,不适合多分类任务;
- 不适合太离散的分类、样本类别不平衡的分类、非凸形状的分类。
2.改进方法
(1)数据预处理
均值和方差大的维度将对数据的聚类产生决定性影响。所以未做归一化处理和统一单位的数据是无法直接参与运算和比较的。
常见的数据预处理方式有:数据归一化,数据标准化。
此外,离群点或者噪声数据会对均值产生较大的影响,导致中心偏移,因此我们还需要对数据进行异常点检测。
(2)合理选择k值
常见的选取 K 值的方法有:手肘法、Gap statistic法。
a.手肘法
核心指标:SSE(误差平方和)

Ci是第i个簇;P是Ci中的样本点;mi是Ci的质心;
SSE是所有样本的聚类误差,代表了聚类的好坏。
思想:随着聚类数k的增大,样本划分会更加精细,每个簇的聚合程度会逐渐提高,那么误差平方和SSE自然会逐渐变小;
当k小于真实聚类数时,由于k的增大会大幅增加每个簇的聚合程度,故SSE的下降幅度会很大;
而当k到达真实聚类数时,再增加k所得到的聚合程度回报会迅速变小,所以SSE的下降幅度会骤减,然后随着k值的继续增大而趋于平缓;
也就是说SSE和k的关系图是一个手肘的形状,而这个肘部对应的k值就是数据的真实聚类数;
b.轮廓系数法
该方法的核心指标是轮廓系数(Silhouette Coefficient),某个样本点Xi的轮廓系数定义如下:

其中,a是Xi与同簇的其他样本的平均距离,称为凝聚度,b是Xi与最近簇中所有样本的平均距离,称为分离度。而最近簇的定义是:
其中p是某个簇Ck中的样本。
用Xi到某个簇所有样本平均距离作为衡量该点到该簇的距离后,选择离Xi最近的一个簇作为最近簇。
求出所有样本的轮廓系数后再求平均值就得到了平均轮廓系数。平均轮廓系数的取值范围为[-1,1],且簇内样本的距离越近,簇间样本距离越远,平均轮廓系数越大,聚类效果越好。
平均轮廓系数最大的k便是最佳聚类数。
(3)采用核函数
K-means 假设了各个数据簇的数据具有一样的的先验概率并呈现球形分布,但这种分布在实际生活中并不常见;
面对非凸的数据分布形状时我们可以引入核函数来优化,称为核 K-means 算法,是核聚类方法的一种;
核聚类的主要思想是通过一个非线性映射,将输入空间中的数据点映射到高位的特征空间中,并在新的特征空间中进行聚类。
(4)k-means++
对初始值选择的改进;
原理:在选取第一个聚类中心(n=1)时同样通过随机的方法;
假设已经选取了n个初始聚类中心(0<n<K),则在选取第n+1个聚类中心时:距离当前n个聚类中心越远的点会有更高的概率被选为第n+1个聚类中心;
(聚类中心互相离得越远越好)
(5)二分k-means
原理:主要优化的地方是在选取质心的时候,二分K-Means算法有效地避免了在初始选取质心时的误差,可以有效地提高算法效率;
二分K-Means算法首先将所有点作为一个簇,然后将该簇一分为二。之后选择其中一个簇继续进行划分,选择哪一个簇进行划分取决于对其划分是否可以最大程度降低SSE的值。
上述基于SSE的划分过程不断重复,直到得到用户指定的簇数目为止。
步骤:a.所有点作为一个簇;
b.将该簇一分为二;
c.选择能最大限度降低SSE的簇划分为两个簇;(即再次划分较为松散的簇);
d.以此进行下去,直到簇的数目等于用户给定的数目k为止。

二分均值算法可以加速k-means算法的执行速度,因为它的相似度计算少了并且不受初始化问题的影响,不存在随机点的选取,且每一步都保证了误差最小。
……k-means算法,k-means++算法,二分k-means算法的python实现见下篇……
浙公网安备 33010602011771号