关注咱们的公众号哦!获取更多精彩哦!算法
假若有这样一种状况,在一天你想去某个城市旅游,这个城市里你想去的有70个地方,如今你只有每个地方的地址,这个地址列表很长,有70个位置。事先确定要作好攻略,你要把一些比较接近的地方放在一块儿组成一组,这样就能够安排交通工具抵达这些组的“某个地址”,而后步行到每一个组内的地址。那么,如何肯定这些组,如何肯定这些组的“某个地址”?答案就是聚类。而本文所提供的k-means聚类分析方法就能够用于解决这类问题。数组
聚类是一个将数据集中在某些方面类似的数据成员进行分类组织的过程。k均值聚类是最著名的划分聚类算法,因为简洁和效率使得他成为全部聚类算法中最普遍使用的。给定一个数据点集合和须要的聚类数目k,k由用户指定,k均值算法(k-means)根据某个距离函数反复把数据分入k个聚类中。k-means 算法的工做过程说明以下:首先从n个数据对象任意选择 k 个对象做为初始聚类中心;而对于所剩下其它对象,则根据它们与这些聚类中心的类似度(距离),分别将它们分配给与其最类似的(聚类中心所表明的)聚类;而后再计算每一个所获新聚类的聚类中心(该聚类中全部对象的均值);不断重复这一过程直到标准测度函数开始收敛为止。通常都采用均方差做为标准测度函数。app
用如下例子加以解释:函数
图1:给定一个数据集;工具
图2:根据K = 5初始化聚类中心,保证 聚类中心处于数据空间内;学习
图3:根据计算类内对象和聚类中心之间的类似度指标,将数据进行划分;编码
图4:将类内之间数据的均值做为聚类中心,更新聚类中心。url
最后判断算法结束与否便可,目的是为了保证算法的收敛。3d
以往的回归分类、朴素贝叶斯分类、SVM分类的样本的标签是已知的,经过大量的训练样本获得模型,而后判断新的样本所属已知类别中的哪一类。而k-means聚类属于无监督学习,样本所属的类别是未知的,只是根据特征将样本分类,且类别空间也是根据人为须要选定的。code
K-means核心思想:最小化全部样本到所属类别中心的欧式距离和,采用迭代的方式实现收敛。
K-means算法的具体步骤以下:
1)原理比较简单,实现也是很容易,收敛速度快。
2)聚类效果较优。
3)算法的可解释度比较强。
4)主要须要调参的参数仅仅是簇数k。
1)K值的选取很差把握
2)对于不是凸的数据集比较难收敛
3)若是各隐含类别的数据不平衡,好比各隐含类别的数据量严重失衡,或者各隐含类别的方差不一样,则聚类效果不佳。
4)采用迭代方法,获得的结果只是局部最优。
5)对噪音和异常点比较的敏感。
6)可能收敛到局部最小值,在大规模数据集上收敛较慢。
聚类是一种无监督的学习,它将类似的对象归到同一簇中。聚类的方法几乎能够应用全部对象,簇内的对象越类似,聚类的效果就越好。K-means算法中的k表示的是聚类为k个簇,means表明取每个聚类中数据值的均值做为该簇的中心,或者称为质心,即用每个的类的质心对该簇进行描述。聚类和分类最大的不一样在于,分类的目标是事先已知的,而聚类则不同,聚类事先不知道目标变量是什么,类别没有像分类那样被预先定义出来,因此,聚类有时也叫无监督学习。聚类分析试图将类似的对象纳入同一簇,将不类似的对象归为不一样簇,那么,显然须要一种合适的类似度计算方法,咱们已知的有不少类似度的计算方法,好比欧氏距离,余弦距离,汉明距离等。事实上,咱们应该根据具体的应用来选取合适的类似度计算方法。 固然,任何一种算法都有必定的缺陷,没有一种算法时完美的,有的只是人类不断追求完美,不断创新的意志。K-means算法也有它的缺陷,可是咱们能够经过一些后处理来获得更好的聚类结果,这些在后面都会讲到。K-means算法虽然比较容易实现,可是其可能收敛到局部最优解,且在大规模数据集上收敛速度相对较慢。
首先,随机肯定k个初始点的质心;而后将数据集中的每个点分配到一个簇中,即为每个点找到距其最近的质心,并将其分配给该质心所对应的簇;该步完成后,每个簇的质心更新为该簇全部点的平均值。具体算法表示以下:下图展现了K-means聚类算法的支持函数在Python环境下的具体表示:
在上述算法清单中,包含了几个K-均值算法中要用到的辅助函数。LoadDataSet()函数是将文本文件导入到列表中,文本文件每一行为tab分隔的浮点数,每个列表会被添加到dataMat中,最后返回dataMat;函数distEclud()用于计算两个向量的欧式距离;函数randCent()为给定数据集构建一个包含k个随机质心的集合。下图表示以上3个函数的实际效果。
若是3个支持函数均可以正常运行,就能够准备实现完整的K-means算法了,该算法会建立K个质心,而后将每一个点分配到最近的质心,再从新计算质心,直到数据点的簇分配结果再也不改变为止。具体代码以下:
上面的代码给出了完整的K-means算法。上述算法的运行逻辑以下:在第一步创建的Kmeans()函数接受4个输入参数。只有数据集及簇的数目是必选的,而用来计算距离(咱们这里用的是欧式距离)和建立初始质心的函数都是可选的(这里用的是randCent函数)。Kmeans()函数一开始肯定数据集中数据点的总数,而后建立一个矩阵来存储每一个点的簇分配结果。这个矩阵clusterAssment有两列:簇索引值和聚类偏差。
按照上述方式反复迭代,直到全部数据点的簇分配结果再也不改变为止。程序中建立一个标志变量clusterChanged,若是该值为True,则继续迭代。上述迭代使用while循环来实现。接下来遍历全部数据找到距离每一个点最近的质心(经过对每一个点遍历全部质心并计算点到每一个质心的欧式距离)。若是任一点的簇分配结果发生改变,则更新clusterChanged标志。最后遍历全部质心并更新它们的取值,具体实现步骤以下:经过数组过滤来得到给定簇的全部点;而后计算全部点的均值,选项axis=0表示沿矩阵的列方向进行均值计算;最后程序返回全部的类质心和点分配结果。
算法的运行效果以下图所示,咱们能够看到上面的结果通过了3次迭代以后k-means算法收敛:
K-means算法进行到这里,咱们彷佛已经得出了聚类的质心,可是不要忘记了咱们的算法采起的是随机初始化k个簇的质心的方法,这样的话聚类效果可能会陷入局部最优解的状况,这样虽然有效果,但不如全局最优解的效果好。所以接下来的二分K--means算法就是针对这一问题所采起的相应的后处理,使算法跳出局部最优解,达到全局最优解,得到最好的聚类效果。二分K-means算法首先将全部点做为一个簇,而后将簇一分为二,以后选择其中一个簇继续进行划分,选择哪个簇取决于对其划分是否可以最大程度地下降SSE(偏差平方和,即clusterAssment矩阵的第一列之和)的值。具体的代码以下:
这个函数首先建立一个矩阵来存储数据集中每一个点的簇分配结果及平方偏差,而后计算整个数据集的质心,并使用一个列表来保留全部的质心。获得上述质心之后,能够遍历数据集中全部点来计算每一个点到质心的偏差值(后面会用到)。而后程序进入while循环,该循环会不停划分簇,直到获得想要的簇数目为止。具体循环作法如上图所示,当while循环结束时,函数返回质心列表与簇分配结果。下图展现了一个上面全部算法一块儿运行的结果:
二分k-means算法中,直到簇的数目达到k值,算法才会中止。在算法中经过将全部的簇进行划分,而后分别计算划分后全部簇的偏差。选择使得总偏差最小的那个簇进行划分。划分完成后,要更新簇的质心列表,数据点的分类结果及偏差平方。具体地,假设划分的簇为m(m<k)个簇中的第i个簇,那么这个簇分红的两个簇后,其中一个取代该被划分的簇,成为第i个簇,并计算该簇的质心;此外,将划分获得的另一个簇,做为一个新的簇,成为第m+1个簇,并计算该簇的质心。此外,算法中还存储了各个数据点的划分结果和偏差平方,此时也应更新相应的存储信息。这样,重复该过程,直至簇个数达到k。经过上述算法,以前陷入局部最小值的的这些数据,通过二分K-means算法屡次划分后,逐渐收敛到全局最小值,从而达到了使人满意的聚类效果。
回到刚开始的问题,咱们如今有70个地方的地址,可是只知道地址是不够的,咱们须要知道的是这些地址之间的距离远近信息。所以,咱们须要获得每一个地址的经度和纬度,而后对这些地址进行聚类以安排行程。具体的地址转换与算法过程以下所示:
这一部分属于数据预处理工做,在上述代码中,首先建立一个字典,字典里面存储的是经过URL获取经纬度所必要的参数,即咱们想要的返回的数据格式flogs=J;获取数据的appid;以及要输入的地址信息(stAddress,city)。而后,经过urlencode()函数帮助咱们将字典类型的信息转化为URL能够传递的字符串格式。最后,打开URL获取返回的JSON类型数据,经过JSON工具来解析返回的数据。且在返回的结果中,当错误编码为0时表示,获得了经纬度信息,而为其余值时,则表示返回经纬度信息失败。此外,在代码中,每次获取完一个地点的经纬度信息后,延迟一秒钟。这样作的目的是为了不频繁的调用API,请求被封掉的状况。接下来就要正式利用k—means聚类方法对地理坐标进行聚类。
将上述算法加入到第三部分“算法示例”中的算法中,而后在Python提示符下输入以下图所示的命令,获得的结果以下图所示:
执行上面的命令以后,最后得出的聚类结果以下图所示:
责编 | 薛 李 蔡 孙 赵
指导 | 老薛
指导教授简介:
薛巍立,男,博士,东南大学经济管理学院教授,博士生导师,国家天然科学基金优秀青年基金项目得到者。博士毕业于香港中文大学系统工程与工程管理系,主要从事供应链物流管理、运营风险管理和医疗服务运做管理等。主要成果发表在Operations Research、Production and Operations Management、Transportation Science、European Journal of Operational Research、Operations Research Letters等期刊上。