算法思想
为了将集合S分成k个类,可以先选取k个中心点,将S中样本划分到其中的某个类别中,然后对划分的k个类重新选择中心点,进而重新划分,直至中心点稳定。
算法伪代码
List K_means(DataSet S, int k)
{
List new_centrio_list = Select_init_centriole(S, k); // 选取初始的k个中心点
do {
centrio_list = new_centrio_list;
foreach (s in S) {
best_centri->distance = MAX;
best_centri->class = Undefine;
foreach (centri in centrio_list) {
double distance = Calculate_distance(s, centri);
if(best_centri->distance > distance) {
best_centri->distance = distance;
best_centri->class = centri->tag;
}
}
category_list[best_centri->class].Add(s);
}
new_centrio_list = Relocate_centriole(category_list, centrio_list, k);
} while(!Is_centrio_stable(new_centrio_list, centrio_list));
return category_list;
}
算法分析
1.时间复杂性:O(nkt),其中n=|S|,t为迭代的次数。每次迭代均要计算S中的每个样本同每个中心点的距离,然后将其归类为最小距离的中心点。
2.Select_init_centriole(S,k)函数是初始种子的选择,传统的K-means算法采用的爬山法,初始种子的选择决定了最后收敛的效果,现在有多种方法选择种子值。同时k的设定,在k未知时,如何自动选择k值,现在也已经有了很多方法,后面用到再继续研究。
3.Calculate_distance(s,centri)函数用于计算两个样本点之间的距离。距离的计算方法有很多种,最常用的距离计算公式是用阿几里德距离,但是这不一定是最优的选择。因此,距离计算也是K-means算法中需要探讨的一个问题。
4.Relocate_centriole(category_list,centrio_list,k)函数用于重置中心点。重置的方法主要有两种:k均值和k中心点。前者是将划归的各个类属样本的均值作为新的中心点,而后者是选择各个类簇的中心样本作为新的中心点。后者一般情况下具有更高的容错能力,对于噪点和离群点有更好的容错力。
5.K-means算法对离群点和噪声是非常敏感的,因此需要考虑一些策略对噪声和离群点进行处理。
Reference
1.韩家炜,《数据挖掘:概念与技术》
2.Xindong Wu, Top 10 algorithms in datamining