一.k-means算法
1.概念
事先确定常数K,常数K意味着最终的聚类类别数,首先随机选定初始点为质心,并通过计算每一个样本与质心之间的相似度(这里为欧式距离),将样本点归到最相似的类中,接着,重新计算每个类的质心(即为类中心),重复这样的过程,知道质心不再改变,最终就确定了每个样本所属的类别以及每个类的质心。
![]()
由于每次都要计算所有的样本与每一个质心之间的相似度,故在大规模的数据集上,K-Means算法的收敛速度比较慢。
2.聚类和分类算法
(1)聚类算法
无监督学习算法,主要用于将相似的样本自动归到一个类别中.
…
在聚类算法中根据样本之间的相似性,将样本划分到不同的类别中,对于不同的相似度计算方法,会得到不同的聚类结果,常用的相似度计算方法有欧式距离法。
(2)和分类算法区别
聚类算法是无监督的学习算法,而分类算法属于监督的学习算法.
3.算法流程

(1)选择聚类的个数k.
(2)任意产生k个聚类,然后确定聚类中心,或者直接生成k个中心。
(3)对每个点确定其聚类中心点。
(4)再计算其聚类新中心。
(5)重复以上步骤直到满足收敛要求。(通常就是确定的中心点不再改变。)
结论: K-Means 一定会停下,不可能陷入一直选质心的过程.
4.优点
(1)原理简单(靠近中心点),实现容易.
(2)聚类效果中上(依赖K的选择).
(3)空间复杂度o(N,样本点个数),时间复杂度o(I*K*N,迭代次数,中心点个数,样本点个数).
5.缺点
(1)对离群点,噪声敏感 (中心点易偏移)
(2)很难发现大小差别很大的簇及进行增量计算.
(3)结果不一定是全局最优,只能保证局部最优(与K的个数及初值选取有关).
6.K值确定
(1)肘方法
Elbow method 就是“肘”方法,对于n个点的数据集,迭代计算k from 1 to n,每次聚类完成后计算每个点到其所属的簇中心的距离的平方和,可以想象到这个平方和是会逐渐变小的,直到k==n时平方和为0,因为每个点都是它所在的簇中心本身。但是在这个平方和变化过程中,会出现一个拐点也即“肘”点,下图可以看到下降率突然变缓时即认为是最佳的k值。
(2)肘方法的核心指标
肘方法的核心指标是SSE(sum of the squared errors,误差平方和),Ci是第i个簇,p是Ci中的样本点,mi是Ci的质心(Ci中所有样本的均值),SSE是所有样本的聚类误差,代表了聚类效果的好坏。
(3)肘方法的核心思想
随着聚类数k的增大,样本划分会更加精细,每个簇的聚合程度会逐渐提高,那么误差平方和SSE自然会逐渐变小。并且,当k小于真实聚类数时,由于k的增大会大幅增加每个簇的聚合程度,故SSE的下降幅度会很大,而当k到达真实聚类数时,再增加k所得到的聚合程度回报会迅速变小,所以SSE的下降幅度会骤减,然后随着k值的继续增大而趋于平缓,也就是说SSE和k的关系图是一个手肘的形状,而这个肘部对应的k值就是数据的真实聚类数。这也是该方法被称为肘方法的原因。
7.代码演示
import numpy as np
from sklearn.cluster import KMeans
from scipy.spatial.distance import cdist
import matplotlib.pyplot as plt
cluster1 = np.random.uniform(0.5, 1.5, (2, 10))
cluster2 = np.random.uniform(3.5, 4.5, (2, 10))
X = np.hstack((cluster1, cluster2)).T
K = range(1, 10)
meandistortions = []
for k in K:
kmeans = KMeans(n_clusters=k)
kmeans.fit(X)
meandistortions.append(sum(np.min(cdist(X,
kmeans.cluster_centers_, 'euclidean'), axis=1)) / X.shape[0])
plt.plot(K, meandistortions, 'bx-')
plt.xlabel('k')
plt.ylabel('Ave Distor')
plt.title('Elbow method value K')
plt.show()

二.轮廓系数法
1.概念
轮廓系数法 (Silhouette Coefficient)结合了聚类的凝聚度(Cohesion)和分离度(Separation),用于评估聚类的效果。该值处于-1~1之间,值越大,表示聚类效果越好。
![]()
a是Xi与同簇的其他样本的平均距离,称为凝聚度;b是Xi与最近簇中所有样本的平均距离,称为分离度。
2.最近簇的定义
![]()
其中p是某个簇Ck中的样本。即,用Xi到某个簇所有样本平均距离作为衡量该点到该簇的距离后,
…
求出所有样本的轮廓系数后再求平均值就得到了平均轮廓系数。平均轮廓系数的取值范围为[-1,1],且簇内样本的距离越近,簇间样本距离越远,平均轮廓系数越大,聚类效果越好。
3.通过sklearn验证轮廓系数方法
轮廓系数取值为[-1, 1],其值越大越好,且当值为负时,表明 ai小于bi,样本被分配到错误的簇中,聚类结果不可接受。 对于接近0的结果,则表明聚类结果有重叠的情况。
4.实现效果图
三.Canopy算法配合初始聚类
1.概念
Canopy聚类最大的特点是不需要事先指定k值(即clustering的个数),因此具有很大的实际应用价值。Canopy聚类
虽然精度较低,但其在速度上有很大优势,因此可以使用Canopy聚类先对数据进行“粗”聚类,得到k值后再使用
K-means进行进一步“细”聚类。
2.Canopy+Kmeans
(1) 聚类最耗费计算的地方是计算对象相似性的时候,Canopy聚类在第一阶段选择简单、计算代价较低的方法计算对象相似性,将相似的对象放在一个子集中,这个子集被叫做Canopy ,通过一系列计算得到若干Canopy,Canopy之间可以是重叠的,但不会存在某个对象不属于任何Canopy的情况,可以把这一阶段看做数据预处理.
(2) 在各个Canopy 内使用传统的聚类方法(如K-means),不属于同一Canopy 的对象之间不进行相似性计算。(即,根据Canopy算法产生的Canopies代替初始的K个聚类中心点,由于已经将所有数据点进行Canopies有覆盖划分,在计算数据离哪个k-center最近时,不必计算其到所有k-centers的距离,只计算和它在同一个Canopy下的k-centers这样可以提高效率).
3.Canopy详解

(1)首先选择两个距离阈值:T1和T2,其中T1 > T2
(2)从list中任取一点P,用低计算成本方法快速计算点P与所有Canopy之间的距离(如果当前不存在Canopy,则把点P作为一个Canopy),如果点P与某个Canopy距离在T1以内,则将点P加入到这个Canopy
(3)如果点P曾经与某个Canopy的距离在T2以内,则需要把点P从list中删除,这一步是认为点P此时与这个Canopy已经够近了,因此它不可以再做其它Canopy的中心了
(4)重复步骤2、3,直到list为空结束
4.优点
(1)Kmeans对噪声抗干扰较弱,通过Canopy对比,将较小的NumPoint的Cluster直接去掉有利于抗干扰.
(2)Canopy选择出来的每个Canopy的centerPoint作为K会更精确.
(3)只是针对每个Canopy的内做Kmeans聚类,减少相似计算的数量.
5.缺点
算法中T1、T2(T2 < T1)的确定问题,不容易确定.
三.Calinski-Harabasz
类别内部数据的协方差越小越好,类别之间的协方差越大越好,这样的Calinski-Harabasz分数s会高,分数s高则聚类效果越好
![]()
其中m为训练集样本数,k为类别数。B k 为类别之间的协方差矩阵,W k 为类别内部数据的协方差矩阵。tr为矩阵的迹。
四.算法优化
1.K-means++
假设已经选取了n个初始聚类中心(0小于n小于K),则在选取第n+1个聚类中心时:距离当前n个聚类中心越远的点会有更高的概率被选为第n+1个聚类中心。
2.ISODATA
对类别数的“合并”:(当聚类结果某一类中样本数太少,或两个类间的距离太近时),“分裂”(当聚类结果中某一类的类内方差太大,将该类进行分裂)
3.Kernel k-means
将每个样本进行一个投射到高维空间的处理,然后再将处理后的数据使用普通的k-means算法思想进行聚类。
4.二分K-means
首先将所有点作为一个簇,然后将该簇一分为二。之后选择能最大限度降低聚类代价函数(也就是误差平方和)的簇划分为两个簇。以此进行下去,直到簇的数目等于用户给定的数目k为止。隐含的一个原则就:因为聚类的误差平方和能够衡量聚类性能,该值越小表示数据点越接近于他们的质心,聚类效果就越好。所以我们就需要对误差平方和最大的簇进行再一次划分,因为误差平方和越大,表示该簇聚类效果越不好,越有可能是多个簇被当成了一个簇,所以我们首先需要对这个簇进行划分。
5.Mini Batch K-Means
适用大数据的聚类算法
Mini Batch的好处是计算过程中不必使用所有的数据样本,而是从不同类别的样本中抽取一部分样本来代表各自类型进行计算。由于计算样本量少,所以会相应的减少运行时间,但另一方面抽样也必然会带来准确度的下降。
步骤:
(1)从数据集中随机抽取一些数据形成小批量,把他们分配给最近的质心
(2)更新质心
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import MiniBatchKMeans, KMeans
from sklearn import metrics
from sklearn.datasets.samples_generator import make_blobs
# X为样本特征,Y为样本簇类别, 共1000个样本,每个样本4个特征,共4个簇,
簇中心在[-1,-1], [0,0],[1,1], [2,2], 簇方差分别为[0.4, 0.2, 0.2]
X, y = make_blobs(n_samples=1000, n_features=2, centers=[[-1,-1], [0,0], [1,1], [2,2]],
cluster_std=[0.4, 0.2, 0.2, 0.2],
random_state =9)
plt.scatter(X[:, 0], X[:, 1], marker='o')
plt.show() # 图1
for index, k in enumerate((2,3,4,5)):
plt.subplot(2,2,index+1)
y_pred = MiniBatchKMeans(n_clusters=k, batch_size = 200,
random_state=9).fit_predict(X)
score= metrics.calinski_harabaz_score(X, y_pred)
plt.scatter(X[:, 0], X[:, 1], c=y_pred)
plt.text(.99, .01, ('k=%d, score: %.2f' % (k,score)),
transform=plt.gca().transAxes, size=10,
horizontalalignment='right')
plt.show()







6541



被折叠的 条评论
为什么被折叠?



