Kmeans聚类算法分析(转帖)

原帖地址:http://www.opencvchina.com/thread-749-1-1.html


      k-means是一种聚类算法,这种算法是依赖于点的邻域来决定哪些点应该分在一个组中。当一堆点都靠的比较近,那这堆点应该是分到同一组。使用k-means,可以找到每一组的中心点。当然,聚类算法并不局限于2维的点,也可以对高维的空间(3维,4维,等等)的点进行聚类,任意高维的空间都可以。
224002qt15h3l23zeh5thd
      上图中的彩色部分是一些二维空间点。上图中已经把这些点分组了,并使用了不同的颜色对各组进行了标记。这就是聚类算法要做的事情。

K-means算法:
这个算法的输入是:
1:点的数据(这里并不一定指的是坐标,其实可以说是向量)
2:K,聚类中心的个数(即要把这一堆数据分成几组)

      所以,在处理之前,你先要决定将要把这一堆数据分成几组,即聚成几类。但并不是在所有情况下,你都事先就能知道需要把数据聚成几类的。但这也并不意味着使用k-means就不能处理这种情况,下文中会有讲解。
把相应的输入数据,传入k-means算法后,当k-means算法运行完后,该算法的输出是:
1:标签(每一个点都有一个标签,因为最终任何一个点,总会被分到某个类,类的id号就是标签)
2:每个类的中心点。

     标签,是表示某个点是被分到哪个类了。例如,在上图中,实际上有4中“标签”,每个“标签”使用不同的颜色来表示。所有黄色点我们可以用标签0表示,所有橘色点可以用标签1来表示,等等。
主体算法分析
步骤1:得到数据集
224116z7i24tai7ia2tjtu
      在本文中,使用上图的二维坐标(x,y)向量为数据集。假设我们要将这些点聚成5类,即k=5。我们可以看出,有3个类离的比较远,有两个类离得比较近,几乎要混合在一起了。
      当然,数据集不一定是坐标,假如你要对彩色图像进行聚类,那么你的向量就可以是(b,g,r),如果使用的是hsv颜色空间,那还可以使用(h,s,v),当然肯定可以有不同的组合例如(b*b,g*r,r*b) ,(h*b,s*g,v*v)等等。
步骤2:产生初始的类中心
224213344uk41rnl455pkj
      在本文中,初始的类的中心点是随机产生的。如上图的红色点所示,是本文随机产生的初始点。注意观察那两个离得比较近的类,它们几乎要混合在一起,看看算法是如何将它们分开的。
      类的初始中心点是随机产生的。算法会不断迭代来矫正这些中心点,并最终得到比较靠近真实中心点的一组中心点。当然,最终的结果不一定就是真实的那一组中心点,算法会尽量向真实的靠近。
步骤3:根据中心点,划分其他点的归属(归属于哪个类)
224334rf6cczaf6pzgygdf
      每个点(除了中心点的其他点)都计算与5个中心点的距离,选出一个距离最小的(例如该点与第2个中心点的距离是5个距离中最小的),那么该点就归属于该类.上图是点的归类结果示意图.
步骤4:重新计算中心点
224437bsarapucokvus7pv
      经过步骤3后,每一个中心center(i)点都有它的”管辖范围”,由于这个中心点不一定是这个管辖范围的真正中心点,所以要重新计算中心点,计算的方法有很多种,最简单的一种是,直接计算该管辖范围内所有点的均值,做为心的中心点new_center(i)。
      如果重新计算的中心点new_center(i)与原来的中心点center(i)的距离大于一定的阈值(该阈值可以设定),那么认为算法尚未收敛,使用new_center(i)代替center(i)(如图,中心点从红色点转移到绿色点),转步骤3;否则,认为算法已经收敛,则new_center(i)就是最终的中心点。
步骤5:结束
224549etoo3t99utx0f1lz
      现在,所有的中心都不再移动,即算法已经收敛。当然,也许这些中心点还没有达到你要的精度,由于计算这些中心点的准确性,会受初始中心点设置的影响。所以,如果初始中心设置的很糟糕,那么得出来的结果也会不理想。
问题及解决方法
使用k-means时,我们遇到了两个困难。
(1)在事先不知道要聚几类的情况下,该怎么办?
      可以从K=1开始,并且k值不断的增加,通常,随着k的增加,类中的方差会急剧的下降,当k达到一定大的时候,方差的下降会明显减慢(至于慢道何种程度,可以设阈值),此时,就选取到了最佳的k值。
(2)初始中心点的设定
      如果初始值没设置好,肯定也不能获得理想的聚类效果。针对这种情况,这里提供两种方法:随机的选取多组中心点,在每一组中心点上,都把kmeans算法运行一次。最后,在选取类间方差最小的一组。通过设定的选初始值方法(这里提供一种,当然自己也可以去构想其他的方法):
1:在数据集上随机选择一个点,做为第一个中心点;
2:在数据集上,选取离第一个中心点最远的一个点做为第二个中心点。
3:在数据集上,选取离第一个和第二个中心最远的点,做为第三个中心。
4:依此计算后续的中心点

你可能感兴趣的:(算法)