【Spark 机器学习】K-means聚类算法(理论篇)

【Spark 机器学习】K-means聚类算法(理论篇)

本博客是【Spark-Python-机器学习】系列的文章。

该系列的文章主要讲解【机器学习】的一些通用算法的原理,并且使用【Python+Spark】来实现。

文章通常分为上下篇(理论篇 与 实践篇)。

如需转载,请附上本文链接:http://blog.csdn.net/cyh_24/article/details/50444111

在机器学习、数据挖掘领域中,K-Means可以说是入门的最简单的算法了。它是一种无监督的基于距离的聚类算法,采用 距离 作为相似性的评价指标,即认为两个对象的距离越近,其相似度就越大。该算法认为簇cluster是由距离靠近的对象组成的,因此把得到紧凑且独立的簇作为最终目标。

K-Means 原理

K-Means 算法将包含 n 个样本的数据集 x 分成 k 个簇, μi 为第 i 簇的中心点(centroid)。K-Means算法的目标就是,选择 k 个centroids,使得类内样本点到其质心的距离平方和最小:

i=0nminμuC(||xjμi||2)

上面的式子通常被看作是K-Means优劣的度量方式,不过它也存在一些不足之处:

  1. 它假设 clusters 是 convex 并且 isotropic,但实际上并不一定。
  2. 它不是一个标准化的度量指标:我们只知道值越低越好,当值为0 的时候达到最优。但是,在非常高的维度空间下,欧氏距离往往会变得膨胀(这就是所谓的“维数灾难”)。通常在使用K-Means算法之前,先用PCA算法降维,可以缓解这个问题,同时还能提高运行速率。

K-Means 步骤

标准的K-Means 算法又被称为Lloyd-Forgy算法,它使用了迭代优化的技术。按下面两个步骤交替进行:

  • 分配:将每个观测分配到聚类中,使得组内平方和(WCSS)达到最小。
  • 更新:计算得到上步得到聚类中每一聚类观测值的图心,作为新的均值点。

注:把 分配 步骤视为 期望 步骤,把 更新 步骤视为 最大化 步骤,可以看到,K-Means算法实际上是期望-最大化算法(EM)的一个变体。

通常来说,这个算法主要分成三个步骤:

  1. 选择初始的簇中心点(最简单的就是随机选取);
  2. 每个样本计算它到各个中心点的距离,选取最小的距离,并将自己归为旗下;
  3. 当所有样本均归完类后,计算每个簇的新的中心点(每个簇样本的均值);
  4. 重复(2),直到迭代次数,或者新中心点与旧中心点距离小于阈值,算法结束。

初始化的方法

通常使用的初始化方式有:Forgy 和 Random Partition。
Forgy:是从数据集中随机选 k 个数据点将它们作为初始的centroids。
Random Partition:随机地为每一观测指定聚类,然后执行“更新(Update)”步骤,即计算随机分配的各聚类的图心,作为初始的均值点。

Forgy 倾向于将初始的中心点分散开来,而Random Partition 则把中心点都放到靠近数据集中心的地方。
在k-harmonic means 和 fuzzy k-means上,Random Partition 的变现更好;而在EM和标准的K-Means上,Forgy 是更好的选择。

【Spark 机器学习】K-means聚类算法(理论篇)_第1张图片

图1、随机取了三个中心点,作为初始点;
图2、找到离各个中心点最近的数据归为一类;
图3、重新计算各个簇的中心点作为新的中心点;
图4、重复步骤2和3;

因为K-Means 是一种启发式的算法,因此,没有理论保证它能够收敛到全局最优,而结果很大程度上往往受初始中心点的影响(K-Means对初始点很敏感)。
因为算法迭代非常快,如果你怕陷入一个局部最优,一个很常用的解决方法是选不同的初始化跑好几次,然后取最好的centroids;

不过还有一种更糟糕的情况是K-Means收敛的非常慢:尤其是已经证明了,某些情况下的点集(甚至在2维空间中),会使得k-均值算法收敛的时间达到指数级 2Ω(n)
好在,实际情况下,这样的点集几乎不会出现:因此,k-均值算法的平滑运行时间是多项式时间的复杂度。

一些K-Means 不work的Case

下面举一些例子(K-Means会不work的情况):

【Spark 机器学习】K-means聚类算法(理论篇)_第2张图片

这种情况,如果是人来聚类的话,分分钟完成啊,但是看看 K-Means的效果:

【Spark 机器学习】K-means聚类算法(理论篇)_第3张图片

简直差成渣了。。。

Cluster 大小不均匀:

【Spark 机器学习】K-means聚类算法(理论篇)_第4张图片

上面这张图,各个cluster的密集程度相差很大,来看看K-Means的效果吧:

【Spark 机器学习】K-means聚类算法(理论篇)_第5张图片

这里发生的事情就比上面的那个效果微妙了。K-Means的目标是最大程度的减少各个簇内的SSE(sum of squared errors)的总和,它会倾向于生成更大的簇。

K-Means 聚类是特殊的矩阵分解问题

我之前写过一篇文章,介绍:【K-Means 聚类是特殊的矩阵分解问题】。
有兴趣的朋友可以移步去看看:http://blog.csdn.net/cyh_24/article/details/50408884

你可能感兴趣的:(spark,python,机器学习,k-means)