当前位置:   article > 正文

k-means聚类中k值与初始簇中心的选择_簇中心初始化

簇中心初始化

1.手肘法

1.1 理论
手肘法的核心指标是 SSE (sum of the squared errors, 误差平方和 ),
其中, Ci是第i个簇 p是Ci中的样本点 mi是Ci的质心 (Ci中所有样本的均值),SSE是所有样本的聚类误差,代表了聚类效果的好坏。
       手肘法的核心思想是: 随着聚类数k的增大 ,样本划分会更加精细, 每个簇的聚合程度会逐渐提高 那么误差平方和SSE自然会逐渐变小 。并且, 当k小于真实聚类数时,由于k的增大会大幅增加每个簇的聚合程度 ,故 SSE的下降幅度会很大 ,而当 k到达真实聚类数时 ,再 增加k所得到的聚合程度回报会迅速变小 ,所以 SSE的下降幅度会骤减 ,然后随着k值的继续增大而趋于平缓,也就是说SSE和k的关系图是一个手肘的形状,而这个 肘部对应的k值就是数据的真实聚类数 。当然,这也是该方法被称为手肘法的原因。
1.2 实践
我们对 预处理后数据.cs v   中的数据利用手肘法选取最佳聚类数k。具体做法是让k从1开始取值直到取到你认为合适的上限(一般来说这个上限不会太大,这里我们选取上限为8),对每一个k值进行聚类并且记下对于的SSE,然后画出k和SSE的关系图( 毫无疑问是手肘形 ),最后选取肘部对应的k作为我们的最佳聚类数。python实现如下:
[python]   view plain   copy
  1. import pandas as pd  
  2. from sklearn.cluster import KMeans  
  3. import matplotlib.pyplot as plt  
  4.   
  5. df_features = pd.read_csv(r'C:\预处理后数据.csv',encoding='gbk'# 读入数据  
  6. '利用SSE选择k'  
  7. SSE = []  # 存放每次结果的误差平方和  
  8. for k in range(1,9):  
  9.     estimator = KMeans(n_clusters=k)  # 构造聚类器  
  10.     estimator.fit(df_features[['R','F','M']])  
  11.     SSE.append(estimator.inertia_)  
  12. X = range(1,9)  
  13. plt.xlabel('k')  
  14. plt.ylabel('SSE')  
  15. plt.plot(X,SSE,'o-')  
  16. plt.show()  
画出的k与SSE的关系图如下:

显然,肘部对于的k值为4,故对于这个数据集的聚类而言,最佳聚类数应该选4


2. 轮廓系数法

2.1 理论
轮廓系数(Silhouette Coefficient)结合了聚类的凝聚度(Cohesion)和分离度(Separation),用于评估聚类的效果。该值处于-1~1之间,值越大,表示聚类效果越好。具体计算方法如下
该方法的核心指标 是轮廓系 数( Silhouette Coefficient ),某个样本点Xi的轮廓系数定义如下:
                                                             
a是Xi与同一个簇内的所有其他样本距离的平均值,称为 凝聚度 ,用于量化簇内的凝聚度
b是Xi选取簇外的一个簇,计算Xi与簇中所有点的平均距离,遍历所有其他簇,找到最近的那个平均距离即为b,标记为Xi的邻居类,称为分离度。用于量化簇之间的分离度。
最近簇 的定义是
                                                     
其中p是某个簇Ck中的样本。事实上,简单点讲,就是用Xi到某个簇所有样本平均距离作为衡量该点到该簇的距离后,选择离Xi最近的一个簇作为最近簇。
求出 所有样本的轮廓系数 后再求 平均值 就得到了 平均轮廓系数 。度量数据聚类的紧密程度。
平均轮廓系数的取值范围为[-1,1],且簇内样本的距离越近,簇间样本距离越远,平均轮廓系数越大,聚类效果越好。那么,很自然地,平均轮廓系数最大的k便是最佳聚类数。
若s小于0,说明Xi与簇内元素的平均距离小于最近的其他簇,表示聚类效果不好
2.2 实践
我们同样使用2.1中的数据集,同样考虑k等于1到8的情况,对于每个k值进行聚类并且求出相应的轮廓系数,然后做出k和轮廓系数的关系图,选取轮廓系数取值最大的k作为我们最佳聚类系数,python实现如下:
[python]   view plain   copy
  1. import pandas as pd  
  2. from sklearn.cluster import KMeans  
  3. from sklearn.metrics import silhouette_score  
  4. import matplotlib.pyplot as plt  
  5.   
  6. df_features = pd.read_csv(r'C:\Users\61087\Desktop\项目\爬虫数据\预处理后数据.csv',encoding='gbk')  
  7. Scores = []  # 存放轮廓系数  
  8. for k in range(2,9):  
  9.     estimator = KMeans(n_clusters=k)  # 构造聚类器  
  10.     estimator.fit(df_features[['R','F','M']])  
  11.     Scores.append(silhouette_score(df_features[['R','F','M']],estimator.labels_,metric='euclidean'))  
  12. X = range(2,9)  
  13. plt.xlabel('k')  
  14. plt.ylabel('轮廓系数')  
  15. plt.plot(X,Scores,'o-')  
  16. plt.show()  

得到聚类数k与轮廓系数的关系图:
                             
可以看到,轮廓系数最大的k值是2,这表示我们的最佳聚类数为2。但是,值得注意的是,从k和SSE的手肘图可以看出,当k取2时,SSE还非常大,所以这是一个不太合理的聚类数,我们退而求其次,考虑轮廓系数第二大的k值4,这时候SSE已经处于一个较低的水平,因此最佳聚类系数应该取4而不是2。
       但是,讲道理,k=2时轮廓系数最大,聚类效果应该非常好,那为什么SSE会这么大呢?在我看来,原因在于轮廓系数考虑了分离度b,也就是样本与最近簇中所有样本的平均距离。为什么这么说,因为从定义上看,轮廓系数大,不一定是凝聚度a(样本与同簇的其他样本的平均距离)小,而可能是b和a都很大的情况下b相对a大得多,这么一来,a是有可能取得比较大的。a一大,样本与同簇的其他样本的平均距离就大,簇的紧凑程度就弱,那么簇内样本离质心的距离也大,从而导致SSE较大。所以,虽然轮廓系数引入了分离度b而限制了聚类划分的程度,但是同样会引来最优结果的SSE比较大的问题,这一点也是值得注意的。
总结
从以上两个例子可以看出,轮廓系数法确定出的最优k值不一定是最优的,有时候还需要根据SSE去辅助选取,这样一来相对手肘法就显得有点累赘。因此,如果没有特殊情况的话,我还是建议首先考虑用手肘法。



关于初始类簇中心点的选取

最简单的确定初始类簇中心点的方法是随机选择K个点作为初始的类簇中心点,但是该方法在有些情况下的效果较差,如下(下图中的数据是用五个二元正态高斯分布生成的,颜色代表聚类效果):
K个初始类簇点的选取还有两种方法:
1)选择彼此距离尽可能远的K个点 
2)先对数据用层次聚类算法或者Canopy算法进行聚类,得到K个簇之后,从每个类簇中选择一个点,该点可以是该类簇的中心点,或者是距离类簇中心点最近的那个点。

1) 选择批次距离尽可能远的K个点
  首先随机选择一个点作为第一个初始类簇中心点,然后选择距离该点最远的那个点作为第二个初始类簇中心点,然后再选择距离前两个点的最近距离最大的点作为第三个初始类簇的中心点,以此类推,直至选出K个初始类簇中心点。

2) 选用层次聚类或者Canopy算法进行初始聚类,然后利用这些类簇的中心点作为KMeans算法初始类簇中心点。
常用的层次聚类算法有BIRCH和ROCK,在此不作介绍,下面简单介绍一下Canopy算法,主要摘自Mahout的Wiki:
  首先定义两个距离T1和T2,T1>T2.从初始的点的集合S中随机移除一个点P,然后对于还在S中的每个点I,计算该点I与点P的距离,如果距离小于T1,则将点I加入到点P所代表的Canopy中,如果距离小于T2,则将点I从集合S中移除,并将点I加入到点P所代表的Canopy中。迭代完一次之后,重新从集合S中随机选择一个点作为新的点P,然后重复执行以上步骤。
  Canopy算法执行完毕后会得到很多Canopy,可以认为每个Canopy都是一个Cluster,与KMeans等硬划分算法不同,Canopy的聚类结果中每个点有可能属于多个Canopy。我们可以选择距离每个Canopy的中心点最近的那个数据点,或者直接选择每个Canopy的中心点作为KMeans的初始K个类簇中心点。
本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/小惠珠哦/article/detail/812989
推荐阅读
相关标签
  

闽ICP备14008679号