K-Means算法是基于原型的聚类算法(也称基于划分的聚类算法)
1.算法流程
输入是样本集
D
=
x
1
,
x
2
,
.
.
.
x
m
D={x_1,x_2,...x_m}
D=x1,x2,...xm,聚类的簇数k,最大迭代次数N
输出是簇划分
C
=
C
1
,
C
2
,
.
.
.
C
k
C={C_1,C_2,...C_k}
C=C1,C2,...Ck
step1.从数据集D中随机选择k个样本作为初始的k个质心向量:
μ
1
,
μ
2
,
.
.
.
,
μ
k
{μ_1,μ_2,...,μ_k}
μ1,μ2,...,μk
step2.对于n=1,2,…,N
- a) 将簇划分C初始化为 C t = ∅ C_t=∅ Ct=∅, t = 1 , 2... k t=1,2...k t=1,2...k
- b)对于i=1,2…m,计算样本 x i x_i xi和各个质心向量 μ j μ_j μj( j = 1 , 2 , . . . k j=1,2,...k j=1,2,...k)的距离: d i j = ∣ ∣ x i − μ j ∣ ∣ 2 2 d_{ij}={|| x_i−μ_j||}_2^2 dij=∣∣xi−μj∣∣22,将 x i x_i xi标记最小的为 d i j d_{ij} dij所对应的类别 λ i λ_i λi。此时更新 C λ i = C λ i ∪ x i C_{λ_i}=C_{λ_i}∪{x_i} Cλi=Cλi∪xi
- c) 对于 j = 1 , 2 , . . . , k , j=1,2,...,k, j=1,2,...,k,对 C j C_j Cj中所有的样本点重新计算新的质心 μ j = 1 ∣ C j ∣ ∑ x ∈ C j x μ_j=\frac1{|C_j|}\sum_{x\in C_j}x μj=∣Cj∣1∑x∈Cjx
- e) 如果所有的k个质心向量都没有发生变化,则转到步骤3)
step3.输出簇划分 C = C 1 , C 2 , . . . C k C={C_1,C_2,...C_k} C=C1,C2,...Ck
2.k-means的优缺点
K-Means的主要优点有:
-
原理比较简单,实现也是很容易,收敛速度快。
-
聚类效果较优。
-
算法的可解释度比较强。
-
主要需要调参的参数仅仅是簇数k。
K-Means的主要缺点有:
- K值的选取不好把握
- 对于不是凸的数据集比较难收敛
- 如果各隐含类别的数据不平衡,比如各隐含类别的数据量严重失衡,或者各隐含类别的方差不同,则聚类效果不佳。
- 采用迭代方法,得到的结果只是局部最优。
- 对噪音和异常点比较的敏感。
3.k-means对数据集的要求
- 数据变量属性为数值型,不能够对名义型数据进行计算;
- 无法计算缺失值数据,如果数据有缺失,必须先进行缺失值替换,替换方法常见的有最大值,最小值,平均值,删除变量等方式;
- 运行效率不高,对于大数据集的处理较慢,对维度敏感,在算法运行前先进行特征选择或者主成分分析
4.k-means算法聚类效果评估
轮廓系数:
轮廓系数(Silhouette Coefficient)结合了聚类的凝聚度(Cohesion)和分离度(Separation),用于评估聚类的效果。该值处于-1~1之间,值越大,表示聚类效果越好。具体计算方法如下:
step1.对于每个样本点
i
i
i,计算点i与其同一个簇内的所有其他元素距离的平均值,记作
a
(
i
)
a(i)
a(i),用于量化簇内的凝聚度。
step2.选取i外的一个簇b,计算i与b中所有点的平均距离,遍历所有其他簇,找到最近的这个平均距离,记作
b
(
i
)
b(i)
b(i),即为i的邻居类,用于量化簇之间分离度。
step3.对于样本点i,轮廓系数
s
(
i
)
=
b
(
i
)
–
a
(
i
)
m
a
x
{
a
(
i
)
,
b
(
i
)
}
s(i) = \frac{b(i) – a(i)} {max\{a(i),b(i) \}}
s(i)=max{a(i),b(i)}b(i)–a(i)
step4.计算所有i的轮廓系数,求出平均值即为当前聚类的整体轮廓系数,度量数据聚类的紧密程度
从上面的公式,不难发现若s(i)小于0,说明i与其簇内元素的平均距离小于最近的其他簇,表示聚类效果不好。如果a(i)趋于0,或者b(i)足够大,即a(i)<<b(i),那么s(i)趋近与1,说明聚类效果比较好。
5.k值的确定方法
5.1 手肘法
核心指标:SSE(sum of the squared errors,误差平方和)
S
S
E
=
∑
i
=
1
k
∑
p
∈
C
i
∣
p
−
m
i
∣
2
SSE=\sum_{i=1}^{k}\sum_{p\in C_i}|p-m_i|^2
SSE=∑i=1k∑p∈Ci∣p−mi∣2
- C i C_i Ci是第i个簇
- p p p是 C i C_i Ci中的样本点
- m i m_i mi是 C i C_i Ci的质心(Ci中所有样本的均值)
- SSE是所有样本的聚类误差,代表了聚类效果的好坏。
手肘法核心思想
- 随着聚类数k的增大,样本划分会更加精细,每个簇的聚合程度会逐渐提高,那么误差平方和SSE自然会逐渐变小。
- 当 k k k小于真实聚类数时,由于 k k k的增大会大幅增加每个簇的聚合程度,故SSE的下降幅度会很大,而当 k k k到达真实聚类数时,再增加 k k k所得到的聚合程度回报会迅速变小,所以SSE的下降幅度会骤减,然后随着 k k k值的继续增大而趋于平缓,也就是说SSE和 k k k的关系图是一个手肘的形状,而这个肘部对应的 k k k值就是数据的真实聚类数
显然,肘部对于的
k
k
k值为4(曲率最高),故对于这个数据集的聚类而言,最佳聚类数应该选4。
5.2 轮廓系数
在实际应用中,由于K-mean一般作为数据预处理,或者用于辅助分聚类贴标签。所以
k
k
k一般不会设置很大。可以通过枚举,令
k
k
k从2到一个固定值如10,在每个
k
k
k值上重复运行数次k-means(避免局部最优解),并计算当前
k
k
k的平均轮廓系数,最后选取轮廓系数最大的值对应的
k
k
k作为最终的集群数目。
6.k-means算法改进
6.1 K-Means++算法
k-means缺点:在k-means算法中, k k k个初始化的质心的位置选择对最后的聚类结果和运行时间都有很大的影响,因此需要选择合适的 k k k个质心。如果仅仅是完全随机的选择,有可能导致算法收敛很慢。K-Means++算法就是对K-Means随机初始化质心的方法的优化。
K-Means++优化策略:
假设已经选取了
n
n
n个初始聚类中心
(
0
<
n
<
K
)
(0<n<K)
(0<n<K),则在选取第
n
+
1
n+1
n+1个聚类中心时:距离当前
n
n
n个聚类中心越远的点会有更高的概率被选为第n+1个聚类中心。在选取第一个聚类中心
(
n
=
1
)
(n=1)
(n=1)时同样通过随机的方法。可以说这也符合我们的直觉:聚类中心当然是互相离得越远越好。这个改进虽然直观简单,但是却非常得有效。
K-Means++算法流程:
6.2 ISODATA算法
k-means缺点:对 k k k值敏感。在K-means中, k k k的值需要预先人为地确定,并且在整个算法过程中无法更改。而当遇到高维度、海量的数据集时,人们往往很难准确地估计出 k k k的大小。
ISODATA优化策略:当属于某个类别的样本数过少时把这个类别去除,当属于某个类别的样本数过多、分散程度较大时把这个类别分为两个子类别。
ISODATA算法流程:
ISODATA算法的输入:
- 预期的聚类中心数目 K 0 K_0 K0:虽然在ISODATA运行过程中聚类中心数目是可变的,但还是需要由用户指定一个参考标准。事实上,该算法的聚类中心数目变动范围也由 K 0 K_0 K0决定。具体地,最终输出的聚类中心数目范围是 [ K 0 2 , 2 K 0 \frac{K_0}2, 2K_0 2K0,2K0]。
- 每个类所要求的最少样本数目 N m i n N_{min} Nmin:用于判断当某个类别所包含样本分散程度较大时是否可以进行分裂操作。如果分裂后会导致某个子类别所包含样本数目小于 N m i n N_{min} Nmin,就不会对该类别进行分裂操作。
- 最大方差Sigma:用于衡量某个类别中样本的分散程度。当样本的分散程度超过这个值时,则有可能进行分裂操作(注意同时需要满足上一条所述的条件)。
- 两个类别对应聚类中心之间所允许最小距离 d m i n d_{min} dmin:如果两个类别靠得非常近(即这两个类别对应聚类中心之间的距离非常小),则需要对这两个类别进行合并操作。是否进行合并的阈值就是由 d m i n d_{min} dmin决定。
ISODATA算法的原理非常直观,不过由于它和其他两个方法相比需要额外指定较多的参数,并且某些参数同样很难准确指定出一个较合理的值,因此ISODATA算法在实际过程中并没有K-means++受欢迎。
ISODATA算法主体部分:
分裂操作:
合并操作:
6.3 elkan K-Means算法
k-means缺点:在传统的K-Means算法中,我们在每轮迭代时,要计算所有的样本点到所有的质心的距离,这样会比较的耗时。
改进思想:减少不必要的距离的计算
利用了两边之和大于等于第三边,以及两边之差小于第三边的三角形性质,来减少距离的计算。
- 第一种规律是对于一个样本点x和两个质心 μ j 1 μ_{j_1} μj1, μ j 2 μ_{j_2} μj2。如果我们预先计算出了这两个质心之间的距离 D ( j 1 , j 2 ) D(j_1,j_2) D(j1,j2),则如果计算发现 2 D ( x , j 1 ) ≤ D ( j 1 , j 2 ) 2D(x,j_1)≤D(j_1,j_2) 2D(x,j1)≤D(j1,j2),我们立即就可以知道 D ( x , j 1 ) ≤ D ( x , j 2 ) D(x,j_1)≤D(x,j_2) D(x,j1)≤D(x,j2)。此时我们不需要再计算 D ( x , j 2 ) D(x,j_2) D(x,j2),也就是说省了一步距离计算。
- 第二种规律是对于一个样本点x和两个质心
μ
j
1
μ_{j_1}
μj1,
μ
j
2
μ_{j_2}
μj2。我们可以得到
D ( x , j 2 ) ≥ m a x { 0 , D ( x , j 1 ) − D ( j 1 , j 2 ) } D(x,j_2)≥max\{{0,D(x,j_1)−D(j_1,j_2)\}} D(x,j2)≥max{0,D(x,j1)−D(j1,j2)}
这个从三角形的性质也很容易得到。
利用上边的两个规律,elkan K-Means比起传统的K-Means迭代速度有很大的提高。但是如果我们的样本的特征是稀疏的,有缺失值的话,这个方法就不使用了,此时某些距离无法计算,则不能使用该算法。
6.4 Mini Batch K-Means
k-means缺点:在统的K-Means算法中,要计算所有的样本点到所有的质心的距离。如果样本量非常大,比如达到10万以上,特征有100以上,此时用传统的K-Means算法非常的耗时,就算加上elkan K-Means优化也依旧。
改进思想:用样本集中的一部分的样本来做传统的K-Means,这样可以避免样本量太大时的计算难题,算法收敛速度大大加快。当然此时的代价就是我们的聚类的精确度也会有一些降低。一般来说这个降低的幅度在可以接受的范围之内。
改进算法:Mini Batch K-Means
选择一个合适的批样本大小batch size,我们仅仅用batch size个样本来做K-Means聚类。那么这batch size个样本怎么来的?一般是通过无放回的随机采样得到的。为了增加算法的准确性,我们一般会多跑几次Mini Batch K-Means算法,用得到不同的随机采样集来得到聚类簇,选择其中最优的聚类簇。
6.5 K-medoids(K-中心点算法)
k-means缺点:对噪声和孤⽴点数据敏感,如簇中含有异常点,将导致均值偏离严重。因为均值体现的是数据集的整体特征,容易掩盖数据本身的特性。
改进思想:不用均值计算法计算质点,用新的方法选取质点。
改进算法: K-medoids
在 K 中心点算法中,每次迭代后的质点都是从聚类的样本点中选取,而选取的标准就是当该样本点成为新的质点后能提高类簇的聚类质量,使得类簇更紧凑。该算法使用绝对误差标准来定义一个类簇的紧凑程度。
S S E = ∑ i = 1 k ∑ p ∈ C i ∣ p − m i ∣ SSE=\sum_{i=1}^{k}\sum_{p\in C_i}|p-m_i| SSE=∑i=1k∑p∈Ci∣p−mi∣
( p p p是簇 C i C_i Ci中的样本点, m i m_i mi是类簇 C i C_i Ci的质点)
如果某样本点成为质点后,绝对误差能小于原质点所造成的绝对误差,那么 K 中心点算法认为该样本点是可以取代原质点的,在一次迭代重计算类簇质点的时候,我们选择绝对误差最小的那个样本点成为新的质点。
算法流程:
step1.首先随机选取一组聚类样本作为中心点集,每个中心点对应一个簇
step2. 计算各样本点到各个中心点的距离(如欧几里德距离),将样本点放入距离中心点最短的那个簇中
step3. 计算各簇中,距簇内各样本点距离的绝对误差最小的点,作为新的中心点,即取:
m
i
=
a
r
g
max
y
∈
C
i
∑
p
∈
C
i
∣
p
−
y
∣
(
i
=
1
,
2
,
.
.
.
,
k
)
m_i=arg\ \max \limits_{y\in C_i} \sum_{p\in C_i}|p-y| \quad (i=1,2,...,k)
mi=arg y∈Cimax∑p∈Ci∣p−y∣(i=1,2,...,k)
step4. 如果新的中心点集与原中心点集相同,算法终止;如果新的中心点集与原中心点集不完全相同,返回step2)
6.6 Kernel K-means
k-means缺点:传统K-means采用欧式距离进行样本间的相似度度量,显然并不是所有的数据集都适用于这种度量方式。
改进思想:参照支持向量机中核函数的思想,将所有样本映射到另外一个特征空间中再进行聚类,就有可能改善聚类效果。
改进算法:Kernel K-means(本文不对Kernel K-means进行详细介绍)