Hello! 七月的小李又上线啦~
今天看视频的时候看到K-means算法 想到之前写过的K-近邻算法的学习(附Python和Matlab实现)就打算把这个算法也整理一下并和之前的KNN对比一下。
——————
在正式写K-means之前需要先了解一个名词:聚类
聚类
聚类,顾名思义,从字面上可以简单的理解为相似元素的一个集合。那么实际上,聚类是属于无监督学习的算法。对于聚类来说,我们不需要有label即标签,只需要有数据(事先不存在类别之分),这些数据通过一定的学习和训练,完成共同的群体聚类。K-means算法是聚类中常用的算法之一。
K-means算法
定义
K-means算法从实现的原理上可以说是基于距离的聚类算法。此算法选取距离作为判断相似性的评价指标,即如果两个元素的距离越近,那么在一定程度上它们的相似度就越大。除此,该算法认为类簇是由距离靠近的元素组成的,因此把得到紧凑且独立的簇作为最终目标,即完成聚类。其主要特点为:各个聚类本身紧凑,且聚类之间要尽可能的分开,有一定的距离。
原理
K-means算法的原理就是通过迭代寻找k个类簇的一种划分方案,使得用这k个类簇的均值来代表相应各类样本时所得的总体误差最小。
k-means算法的基础是最小误差平方和准则。
具体的式子如下,其中μc(i)表示第i个聚类的均值。各类簇内的样本越相似,其与该类均值间的误差平方越小,对所有类所得到的误差平方求和,即可验证分为k类时,各聚类是否是最优的。
(更为详细的解释参见:https://blog.csdn.net/qq_32892383/article/details/80107795)算法步骤
以下图为例说明:初始下为(a)即没有任何labels的数据集,需要达到(f)即分成两个分开的类簇。
1.先随机挑选两个点作为聚类中心(cluster centroids)即(b),K-均值算法是一个迭代过程,分为两部分,第一为簇分类,第二为移动聚类中心。 簇分类是将(b)所有的绿色样本点根据其距离蓝色、红色中心点距离,分配到簇中,染成相应的红色或者蓝色(c)。
2.之后计算染色的点的平均值(平均下来的位置)此时将相应的聚类中心移动到这个均值处(d)。而后再反复进行迭代最终得到(f)。
迭代详细:
因而我们可以概括一下, 也就是主要是计算质心与数据点的距离 ,将数据点分配到距离最近的簇。对每一个簇,计算簇中所有点的均值,并将均值作为质心。这样一个反复迭代的过程。
代码
这边可以利用利用scikit-learn里面的KMeans函数来简单实现from sklean.cluster import KMeans kmeans = KMeans(n_clusters=5) # 获取模型 kmeans.fit(X_train) #这里不需要给他答案 只把要分类的数据给他 即可
更为详细的代码可参考机器学习算法-K-means聚类
K-means算法 VS KNN算法
画个重点!从本质上来说 KNN算法是属于监督学习算法,即有存在Labels,而K-means算法是无监督学习算法,不存在labels.
KNN用于分类,K-means用于聚类。图解对比如下
K-means算法的步骤上面已经写过,下面补充KNN步骤进行对比:
通过对比可以简单概括:这两个算法都是基于距离去计算的、都是需要进行迭代的。但K-means需要选取质心并且改变质心,KNN不存在质心选取,它的训练数据集需要有label或者类别,它额是把没有标签的数据点(样本)自动打上标签或者预测所属类别。
几个问题
1..K-Means算法K值如何选择?
首先,k的取值是没有固定的,不同的k得到的结果会有挺大的不同。如下图所示,左边是k=3的结果,这个就太稀疏了,蓝色的那个簇其实是可以再划分成两个簇的。而右图是k=5的结果,可以看到红色菱形和蓝色菱形这两个簇应该是可以合并成一个簇的。
那么我们可以怎么去选取这个 k更合适?对k的选择可以先用一些算法分析数据的分布,如重心和密度等,然后选择合适的k。
2.如何确定K个簇的初始质心?
选择批次距离尽可能远的K个点。首先随机选择一个点作为第一个初始类簇中心点,然后选择距离该点最远的那个点作为第二个初始类簇中心点,然后再选择距离前两个点的最近距离最大的点作为第三个初始类簇的中心点,以此类推,直至选出K个初始类簇中心点。
参考(http://www.csuldw.com/2015/06/03/2015-06-03-ml-algorithm-K-means/)
其余参考K-means聚类算法及python代码实现
————————————
合格搬运的一天 七月也要努力鸭!顺心yeah!