您好,欢迎来到九壹网。
搜索
您的当前位置:首页K-means聚类算法及python代码实现

K-means聚类算法及python代码实现

来源:九壹网
K-means聚类算法及python代码实现

K-means聚类算法(事先数据并没有类别之分!所有的数据都是⼀样的)1、概述

K-means算法是集简单和经典于⼀⾝的基于距离的聚类算法

采⽤距离作为相似性的评价指标,即认为两个对象的距离越近,其相似度就越⼤。该算法认为类簇是由距离靠近的对象组成的,因此把得到紧凑且独⽴的簇作为最终⽬标。

2、核⼼思想

通过迭代寻找k个类簇的⼀种划分⽅案,使得⽤这k个类簇的均值来代表相应各类样本时所得的总体误差最⼩。k个聚类具有以下特点:各聚类本⾝尽可能的紧凑,⽽各聚类之间尽可能的分开。 k-means算法的基础是最⼩误差平⽅和准则,其代价函数是:

式中,µc(i)表⽰第i个聚类的均值。

各类簇内的样本越相似,其与该类均值间的误差平⽅越⼩,对所有类所得到的误差平⽅求和,即可验证分为k类时,各聚类是否是最优的。上式的代价函数⽆法⽤解析的⽅法最⼩化,只能有迭代的⽅法。

3、算法步骤图解

下图展⽰了对n个样本点进⾏K-means聚类的效果,这⾥k取2。

4、算法实现步骤

k-means算法是将样本聚类成 k个簇(cluster),其中k是⽤户给定的,其求解过程⾮常直观简单,具体算法描述如下:1) 随机选取 k个聚类质⼼点2) 重复下⾯过程直到收敛 {

对于每⼀个样例 i,计算其应该属于的类:

对于每⼀个类 j,重新计算该类的质⼼:

}

其伪代码如下:

******************************************************************************创建k个点作为初始的质⼼点(随机选择)当任意⼀个点的簇分配结果发⽣改变时 对数据集中的每⼀个数据点 对每⼀个质⼼

计算质⼼与数据点的距离 将数据点分配到距离最近的簇

对每⼀个簇,计算簇中所有点的均值,并将均值作为质⼼********************************************************

5、K-means聚类算法python实战需求:

对给定的数据集进⾏聚类

本案例采⽤⼆维数据集,共80个样本,有4个类。

1 #!/usr/bin/python 2 # coding=utf-8

3 from numpy import * 4 # 加载数据

5 def loadDataSet(fileName): # 解析⽂件,按tab分割字段,得到⼀个浮点数字类型的矩阵 6 dataMat = [] # ⽂件的最后⼀个字段是类别标签 7 fr = open(fileName) 8 for line in fr.readlines():

9 curLine = line.strip().split('\')

10 fltLine = map(float, curLine) # 将每个元素转成float类型11 dataMat.append(fltLine)12 return dataMat13

14 # 计算欧⼏⾥得距离

15 def distEclud(vecA, vecB):

16 return sqrt(sum(power(vecA - vecB, 2))) # 求两个向量之间的距离17

18 # 构建聚簇中⼼,取k个(此例中为4)随机质⼼19 def randCent(dataSet, k):20 n = shape(dataSet)[1]

21 centroids = mat(zeros((k,n))) # 每个质⼼有n个坐标值,总共要k个质⼼22 for j in range(n):

23 minJ = min(dataSet[:,j])24 maxJ = max(dataSet[:,j])25 rangeJ = float(maxJ - minJ)

26 centroids[:,j] = minJ + rangeJ * random.rand(k, 1)27 return centroids28

29 # k-means 聚类算法

30 def kMeans(dataSet, k, distMeans =distEclud, createCent = randCent):31 m = shape(dataSet)[0]

32 clusterAssment = mat(zeros((m,2))) # ⽤于存放该样本属于哪类及质⼼距离

33 # clusterAssment第⼀列存放该数据所属的中⼼点,第⼆列是该数据到中⼼点的距离34 centroids = createCent(dataSet, k)

35 clusterChanged = True # ⽤来判断聚类是否已经收敛36 while clusterChanged:

37 clusterChanged = False;

38 for i in range(m): # 把每⼀个数据点划分到离它最近的中⼼点39 minDist = inf; minIndex = -1;40 for j in range(k):

41 distJI = distMeans(centroids[j,:], dataSet[i,:])42 if distJI < minDist:

43 minDist = distJI; minIndex = j # 如果第i个数据点到第j个中⼼点更近,则将i归属为j

44 if clusterAssment[i,0] != minIndex: clusterChanged = True; # 如果分配发⽣变化,则需要继续迭代45 clusterAssment[i,:] = minIndex,minDist**2 # 并将第i个数据点的分配情况存⼊字典46 print centroids

47 for cent in range(k): # 重新计算中⼼点

48 ptsInClust = dataSet[nonzero(clusterAssment[:,0].A == cent)[0]] # 去第⼀列等于cent的所有列49 centroids[cent,:] = mean(ptsInClust, axis = 0) # 算出这些数据的中⼼点50 return centroids, clusterAssment

51 # --------------------测试----------------------------------------------------52 # ⽤测试数据及测试kmeans算法

53 datMat = mat(loadDataSet('testSet.txt'))

54 myCentroids,clustAssing = kMeans(datMat,4)55 print myCentroids56 print clustAssing

运⾏结果:

6、K-means算法补充

K-means算法的缺点及改进⽅法

(1)k值的选择是⽤户指定的,不同的k得到的结果会有挺⼤的不同,如下图所⽰,左边是k=3的结果,这个就太稀疏了,蓝⾊的那个簇其实是可以再划分成两个簇的。⽽右图是k=5的结果,可以看到红⾊菱形和蓝⾊菱形这两个簇应该是可以合并成⼀个簇的:改进:

对k的选择可以先⽤⼀些算法分析数据的分布,如重⼼和密度等,然后选择合适的k

(2)对k个初始质⼼的选择⽐较敏感,容易陷⼊局部最⼩值。例如,我们上⾯的算法运⾏的时候,有可能会得到不同的结果,如下⾯这两种情况。K-means也是收敛了,只是收敛到了局部最⼩值:改进:

有⼈提出了另⼀个成为⼆分k均值(bisecting k-means)算法,它对初始的k个质⼼的选择就不太敏感

(3)存在局限性,如下⾯这种⾮球状的数据分布就搞不定了:

(4)数据集⽐较⼤的时候,收敛会⽐较慢。

上班了,⼯作繁忙,很少看博客了,不能及时给各位数据集,很抱歉,现在决定放在博客⾥⾯,⼤家复制下去使⽤即可:testSet.txt

1.6585 4.285136-3.453687 3.4243214.838138 -1.151539

-5.379713 -3.3621040.9725 2.924086-3.567919 1.5316110.450614 -3.302219-3.487105 -1.7244322.668759 1.594842-3.1585 3.1911373.165506 -3.999838-2.786837 -3.0993544.208187 2.984927-2.123337 2.9433660.704199 -0.479481-0.392370 -3.9637042.831667 1.574018-0.790153 3.3431442.943496 -3.357075-3.195883 -2.2839262.3345 2.875106-1.786345 2.5542482.190101 -1.906020-3.403367 -2.7782881.778124 3.880832-1.688346 2.2302672.592976 -2.054368-4.007257 -3.2070662.257734 3.3875-2.679011 0.7851190.939512 -4.023563-3.674424 -2.2610842.046259 2.735279-3.1470 1.7802694.3726 -0.822248-2.579316 -3.4975761.8034 5.190400-0.798747 2.1855882.836520 -2.658556-3.837877 -3.2538152.096701 3.886007-2.709034 2.9238873.367037 -3.1847-2.121479 -4.2325862.329546 3.1797-3.284816 3.2730993.091414 -3.815232-3.762093 -2.4321913.542056 2.778832-1.736822 4.2410412.127073 -2.983680-4.323818 -3.9381163.792121 5.135768-4.7873 3.3585472.624081 -3.260715-4.009299 -2.9781152.493525 1.963710-2.513661 2.21621.8375 -3.176309-3.171184 -3.5724522.4220 2.4128-2.562539 2.8844383.491078 -3.947487-2.565729 -2.0121143.332948 3.983102-1.616805 3.5731882.280615 -2.559444-2.651229 -3.1031982.321395 3.154987-1.685703 2.9396973.031012 -3.620252-4.599622 -2.1858294.196223 1.126677-2.133863 3.09368.6682 -2.562705-2.793241 -2.1497062.884105 3.043438-2.9677 2.84869.479332 -1.7772-4.905566 -2.911070

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- 91gzw.com 版权所有 湘ICP备2023023988号-2

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务