Python实现K-Means聚类算法
直接上代码^_^
思路:
我们的数据可能是多维的,所以我们把数据当作向量对待。
首先我们需要了解这个算法的特点——需要手动设分类的数量(k)值。
此时类的编号为0~k-1。
然后我们考虑整体的过程。每个类有一个聚类中心(centroid),中心的坐标就是该类每个元素坐标的平均值,对于每一个数据而言,它离哪个中心最近,它就属于哪个类。因此,每次迭代(在KMeansAlgorithm.Iterate方法中实现)时,首先计算每个数据属于哪个类,此时每个类的成员发生了变化,因此需要重新计算每个类的中心(如果不变就说明我们的迭代已经完成了)。
这里我们要注意一下我们选取的距离函数(KMeansAlgorithm.distsquare),它计算两个向量之间欧氏距离的平方:
其中为数据的维数。我们知道,向量点乘它自己就是其模长的平方,这就不难理解代码中对该函数的实现了。
那么问题来了:一开始每个类的情况是怎样的呢?没有初始值就无法进行迭代。这里,我们使用clusmap来表示每个数据属于哪个类,clusmap[3]=0代表第三个元素属于第0类。在setk方法里,我们随机分配每个元素属于的类,用np.random.randint实现。然后计算每个类的中心,这样就完成了初始化,之后就可以开始迭代了。
最后,怎么判断是否结束了呢?我们定义“畸变函数”KMeansAlgorithm.GetDistortion,它等于每个数据到它所在的类的中心的距离的平方和。显然,这个值越低,分类越准确。我们迭代时,如果发现这个值随着迭代的变化小于一定程度(Compute方法的threshold参数),就基本可以判断迭代结束了。threshold代表这一次迭代与上一次迭代相比“畸变”(distortion)的比例,这个值越低,迭代结束的条件越苛刻,运行时间就越长。