我们知道对于K-means算法来说,如果数据样本中出现极端的离群值,导致样本数据分布出现一定的扭曲或者说偏离,则会导致聚类效果不好,与期望的效果之间有误差存在,也就是我们所说的极端值敏感。聚类很多情况下都是通过计算点之间的欧式距离来表现亲缘远近的,所以解决在其上产生的问题就逃不过中心点。这次介绍的k-medoids算法自然在处理一些异常值方面具有得天独厚的优势。
就原理而言,k-means与k-medoids区别在于中心点的选择。前者通过不断产生K个新的中心点(初始为随机,后续计算均值进行)来划分群集,以达到准则函数收敛的结果,其本质就是在不断寻找符合条件的群集重心;后者,顾名思义,不选用平均值,而是选用最中心的点,即需要计算当前簇各个点到中心点的距离。这也使得我们得到一个其与k-means的不同点,或者说k-medoids的性质,它所选取的中心点都是簇中的点。
不过由于算法的复杂性(需要遍历簇中所有点),导致更大的计算资源倾斜。
简单复习一下顺便对比一下两者算法过程:
k-means:
1) 任意选择K个对象作为初始的簇中心;
2) 分别计算数据集中每个元素与所选簇的中心计算距离(一般采用欧式距离),根据最近邻原则,将元素划分到相应的簇中;
3) 计算每个簇中对象的平均值,更新簇的中心;
4) 重复上面的步骤,直至更新的簇的中心与原簇的中心的差值在预定范围内,或者达到预设的迭代次数;
5) 输出K个簇中心。
k-medoids:
1、任意选取 k 个点作为 medoids
2、按照与medoids最近的原则,将剩余点分配到当前最佳的medoids代表的类中
3、在每一类中,计算每个成员点对应的准则函数,选取准则函数最小时对应的点作为新的 medoids
4、重复2-3的过程,直到所有的 medoids 点不再发生变化,或已达到设定的最大迭代次数
其中准则函数为,一类中,某个成员点和其他成员点的距离之和
来一点python的实战
由于可使用的第三方库不多,参考了很多文章和博客,找到了可用的库——pyclust,它还依赖于treelib库。
具体代码如下:
from pyclust import KMedoids
import numpy as np
from sklearn.manifold import TSNE
import matplotlib.pyplot as plt