最近看了下Kmeans算法的源码,层次非常清晰。下面主要是对Kmeans算法中的flags标识的不同的centers生成方法进行梳理。
Kmeans算法中有3中生成centers的算法,分别对应三个flags,KMEANS_RANDOM_CENTERS,KMEANS_PP_CENTERS,KMEANS_USE_INITIAL_LABELS三种。
KMEANS_RANDOM_CENTERS:每个attempts选择随机的初始中心。
KMEANS_PP_CENTERS:用Kmeans++算法
KMEANS_USE_INITIAL_LABELS:第一次attempts用用户提供的labels初始化中心,第二次以及第二次以后的attempts用随机或者半随机中心。
今天主要讲下flags=KMEANS_USE_INITIAL_LABELS时,源码的处理流程。
1)当iter==0时,用用户给定的labels初始化中心,并计算每个中心的样本数。否则,用上一次iter循环后的labels来计算新的中心centers
2)通过第一步统计结果,查找是否有聚类中心的样本数为0,如有,那么找到最大的聚类中心(样本数最多)Max_center;找到Max_center中距离中心点最远的样本;把这个样本点从Max_center中移除,并添加到样本数为0的聚类中心。这样,循环检测每一个聚类中心。生成新的new_centers
3)归一化centers和new_centers,并计算max_center_shift,取max_center_shift为所有聚类中心移动距离的最大值(这个聚类中心的移动距离就是L2距离)
注意:当Iter==0时,max_center_shift为DBL_MAX,这个其实是用户给定的labels初始化聚类中心。
4)计算每个样本值到new_centers的距离,并生成新的labels。然后循环到第一步。
循环终止条件是,当iter达到设定的值或者是当max_center_shift小于给定的精度epsilon时。循环终止,代表一个attempt计算结束。
一个attempt计算基数后,会计算一个compactness,compactness值为所有样本到其距离最近的center的距离之和。