K-means方法是一种非监督学习的算法,它解决的是聚类问题。
1、算法简介:K-means方法是聚类中的经典算法,数据挖掘十大经典算法之一;算法接受参数k,然后将事先输入的n个数据对象划分为k个聚类以便使得所获得的聚类满足聚类中的对象相似度较高,而不同聚类中的对象相似度较小。
2、算法思想:以空间中k个点为中心进行聚类,对最靠近他们的对象归类,通过迭代的方法,逐次更新各聚类中心的值,直到得到最好的聚类结果。
3、算法描述:
(1)适当选择c个类的初始中心;
(2)在第k次迭代中,对任意一个样本,求其到c各中心的距离,将该样本归到距离最短的那个中心所在的类;
(3)利用均值等方法更新该类的中心值;
(4)对于所有的C个聚类中心,如果利用(2)(3)的迭代法更新后,值保持不变,则迭代结束;否则继续迭代。
4、算法举例:
我们假设药物A、B、C、D有两个特征值,分别是药物重量以及PH值。
药物名称 | 药物重量 | 药物PH值 |
---|---|---|
A | 1 | 1 |
B | 2 | 1 |
C | 4 | 3 |
D | 5 | 4 |
现在我们要对这四个药物进行聚类,已知我们要分成两类,那么我们该怎么做呢?
首先我们把上面的数据画到二位坐标系当中 A(1,1),B(2,1),C(4,3),D(5,4):
初始时,由于假设K=2 (表示将所有数据集分为两组,我们称之为聚类) 我们先假设药物A为聚类1的中心点,B为聚类2的中心点。
那么初始时的中心坐标分别为c1=(1,1),c2=(2,1)c1=(1,1),c2=(2,1),矩阵D的第一行代表各个点到中心点c1的距离,第二行代表各个点到中心点c2的距离;那么初始矩阵D0表示成如下:
矩阵 D0向我们展示了除了中心点之外的其他所有点距离K个中心点的距离大小,每个点距离各个中心点的距离都不尽相同。所谓近水楼台先得月,所以将点归入离点最近的中心点一类。以后每开始一次的迭代,都会重新算出每个聚类的中心点,然后根据相同的操作进行点的归类,直到聚类中心不再进行大范围移动或者聚类次数达到要求为止。
矩阵G0代表样本应该归属于哪个聚类,第一行代表各个点是否属于中心c1所在的类(0代表不在,1代表在),第二行代表各个点是否属于中心c2所在的类(0代表不在,1代表在);那么此时G0表示成如下:
由矩阵D0可知A药物属于一个类,B、C、D属于一类;
然后,利用均值等方法更新该类的中心值。
c1=(1,1)
c2=((2+4+5)/3,(1+3+4)/3)= (13/3,8/3)
上图是更新后的坐标图,对应的中心点也发生了变化。
因为中心点跟上次不一样了,所以我们又可以对样本点进行重新划分。划分的方法还是跟以前一模一样,我们先计算出矩阵D1表示成如下:
此时G1表示成如下:
由矩阵G1可知A、B药物属于一个类,C、D属于一类;
然后,利用均值等方法再次更新该类的中心值。
c1=((1+2)/2,(1+1)/2)=(1.5,1)
c2=((4+5)/2,(3+4)/2)=(4.5,3.5)
上图是更新后的坐标图,对应的中心点也发生了变化。
因为中心点跟上次不一样了,所以我们又可以对样本点进行重新划分。划分的方法还是跟以前一模一样,我们先计算出矩阵D2表示成如下:
此时G2表示成如下:
由矩阵G2可知A、B药物属于一个类,C、D属于一类;
然后,利用均值等方法再次更新该类的中心值。
c1=((1+2)/2,(1+1)/2)=(1.5,1)
c2=((4+5)/2,(3+4)/2)=(4.5,3.5)
因为对应的中心点并没有发生变化,所以迭代停止,计算完毕。
本算法的时间复杂度:O(tkmn),其中,t为迭代次数,k为簇的数目,m为记录数,n为维数;
空间复杂度:O((m+k)n),其中,k为簇的数目,m为记录数,n为维数。
适用范围:
K-means算法试图找到使平凡误差准则函数最小的簇。当潜在的簇形状是凸面的,簇与簇之间区别较明显,且簇大小相近时,其聚类结果较理想。前面提到,该算法时间复杂度为O(tkmn),与样本数量线性相关,所以,对于处理大数据集合,该算法非常高效,且伸缩性较好。但该算法除了要事先确定簇数K和对初始聚类中心敏感外,经常以局部最优结束,同时对“噪声”和孤立点敏感,并且该方法不适于发现非凸面形状的簇或大小差别很大的簇。
缺点:
1、聚类中心的个数K 需要事先给定,但在实际中这个 K 值的选定是非常难以估计的,很多时候,事先并不知道给定的数据集应该分成多少个类别才最合适;
2、K-means需要人为地确定初始聚类中心,不同的初始聚类中心可能导致完全不同的聚类结果。(可以使用K-means++算法来解决)
K-means 算法代码实现:
1 | import numpy as np |
执行结果:
K-Means算法需要你指定K值,也就是需要人为指定数据应该分为几组。下一帖我会实现Mean Shift算法,它也是一种聚类算法(Hierarchical),和K-Means(Flat)不同的是它可以自动判断数据集应该分为几组。
在实际数据上应用K-Means算法
1 | import numpy as np |
执行结果:
1 | $ python sk_kmeans.py |
K-means、和KNN算法比较
KNN(K-Nearest Neighbor)介绍
算法思路:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。该方法在定类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。
看下面这幅图:
KNN的算法过程是是这样的:
从上图中我们可以看到,图中的数据集是良好的数据,即都打好了label,一类是蓝色的正方形,一类是红色的三角形,那个绿色的圆形是我们待分类的数据。
如果K=3,那么离绿色点最近的有2个红色三角形和1个蓝色的正方形,这3个点投票,于是绿色的这个待分类点属于红色的三角形
如果K=5,那么离绿色点最近的有2个红色三角形和3个蓝色的正方形,这5个点投票,于是绿色的这个待分类点属于蓝色的正方形
我们可以看到,KNN本质是基于一种数据统计的方法!其实很多机器学习算法也是基于数据统计的。
KNN是一种memory-based learning,也叫instance-based learning,属于lazy learning。即它没有明显的前期训练过程,而是程序开始运行时,把数据集加载到内存后,不需要进行训练,就可以开始分类了。
具体是每次来一个未知的样本点,就在附近找K个最近的点进行投票。
代码实现:
1 | # k-近邻算法根据特征比较,然后提取样本集中特征最相似数据(最邻近)的分类标签 |
总结:
KNN和K-Means的区别
KNN计算方法为:
1计算测试数据与各个训练数据之间的距离;
2按照距离的递增关系进行排序;
3选取距离最小的K个点;
4确定前K个点所在类别的出现频率;
5返回前K个点中出现频率最高的类别作为测试数据的预测分类。
K-means的计算方法为:
1 随机选取k个中心点;
2 遍历所有数据,将每个数据划分到最近的中心点中;
3 计算每个聚类的平均值,并作为新的中心点 ;
4 重复2-3,直到这k个中线点不再变化(收敛了),或执行了足够多的迭代。