《机器学习实战》笔记之十——利用K均值聚类算法对未标注数据分组
来源:互联网 发布:epub手机打开知乎 编辑:程序博客网 时间:2024/05/01 02:16
第十章 利用K均值聚类算法对未标注数据分组
10.1 K-均值聚类算法
K-均值是发现给定数据集的k个簇的算法,每个簇通过其质心来描述。其优点为容易实现,但可能收敛到局部最小值,在大规模数据集上收敛较慢。
随机确定k个初始点为质心,为每个点找距其最近的质心,并将其分配给该质心所对应的簇,每个簇的质心更新为该簇所有点的平均值。质心可用任意距离度量方式,但结果相应的受到距离度量方式影响。伪代码:
coding:
#!/usr/bin/env python# coding=utf-8from numpy import *def loadDataSet(fileName): #导入数据集 dataMat = [] fr = open(fileName) for line in fr.readlines(): curLine = line.strip().split("\t") fltLine = map(float,curLine) dataMat.append(fltLine) return dataMatdef distEclud(vecA, vecB): #欧式距离 return sqrt(sum(power(vecA - vecB, 2)))def randCent(dataSet, k): n = shape(dataSet)[1] #取dataSet的列数 centroids = mat(zeros((k,n))) #每维都创建k个随机数,数在每维最大最小值之间 for j in range(n): minJ = min(dataSet[:,j]) #每维最小值 rangeJ = float(max(dataSet[:,j]) - minJ) centroids[:,j] = minJ + rangeJ*random.rand(k,1) #random.rand(k,1),k个0到1.0之间的随机数 return centroidsdatMat = mat(loadDataSet("testSet.txt"))#print distEclud(datMat[0],datMat[1])def kMeans(dataSet, k, distMeas = distEclud, createCent = randCent): m = shape(dataSet)[0] #取数据的行数 clusterAssment = mat(zeros((m,2))) #创建m*2的矩阵,第一列存簇索引值,第二列存误差 centroids = createCent(dataSet, k) clusterChanged = True while clusterChanged: clusterChanged = False for i in range(m): #对每个数据点来说, minDist = inf minIndex = -1 for j in range(k): #对每维的k个质心,哪个数据点距其最近 distJI = distMeas(centroids[j, :], dataSet[i, :])#距离度量计算质心与数据点之间的距离 if distJI < minDist: #寻找最近质心 minDist = distJI minIndex = j #每个数据点距哪个质心j近,则将其归到j这个质心 if clusterAssment[i,0] != minIndex: #若数据点i的质心是minIndex这个质心,或者说其质心不变的时候,退出循环 clusterChanged = True clusterAssment[i,:] = minIndex, minDist**2 print centroids #打印出每次质心的变化过程 for cent in range(k): ptsInClust = dataSet[nonzero(clusterAssment[:,0].A==cent)[0]]#将所有归为cent这个质心的数据点都提出来,计算均值,更新质心的位置。 centroids[cent,:] = mean(ptsInClust, axis = 0) return centroids, clusterAssmentdatMat = mat(loadDataSet("testSet.txt"))myCentroids, clustAssing = kMeans(datMat, 4)效果:
分析:
从上图可以看出,选定4个簇进行迭代。迭代次数不是确定的,左边10次,右边4次,因为初始质心由随机数生成,迭代次数跟初始质点的选定还是有很大区别的。
10.2 使用后处理来提高聚类性能
K-均值的缺点是需要预先确定簇的数目k,如何确定k的选择是否正确是比较重要的问题。K-均值算法收敛但聚类效果较差的原因是K-均值算法收敛到了局部最小值而非全局最小值。
一种度量聚类效果的指标是SSE(sum of squared error,误差平方和)。SSE值越小表示数据点越接近于它们的质心,聚类效果也越好。可通过增加簇的个数降低SSE,但不符合聚类的目标:保持簇数目不变的情况下提高簇的质量。可以对生成的簇进行后处理,将具有最大SSE值的簇划分成两个簇。将最大簇包含的点过滤出来并在这些点上运行k-均值算法。也可以将两个簇进行合并。
10.3 二分K-均值算法
二分K-均值算法能克服K-均值算法收敛于局部最小值的问题。首先将所有点作为一个簇,然后将该簇一分为二,选择其中一个簇继续划分,选择哪个取决于对其划分是否可以最大程度降低SSE的值,不断划分,直到用户指定的簇数目为止。
伪代码:
将所有点看成一个簇
当簇数目小于k时,对于每一个簇
选择使得误差最小的那个簇进行划分操作计算总误差
在给定的簇上面进行K-均值聚类(k=2)
计算将该簇一分为二之后的总误差
coding
#============二分K-均值聚类算法======================def biKmeans(dataSet, k, distMeas=distEclud): m = shape(dataSet)[0] clusterAssment = mat(zeros((m,2))) centroid0 = mean(dataSet, axis=0).tolist()[0]#计算每维均值,得到质心 centList = [centroid0] #用来保留所有质心 for j in range(m): clusterAssment[j,1] = distMeas(mat(centroid0), dataSet[j,:])**2 while (len(centList) < k): lowestSSE = inf for i in range(len(centList)): ptsInCurrCluster = dataSet[nonzero(clusterAssment[:,0].A==i)[0],:] #get the data points currently in cluster i centroidMat, splitClustAss = kMeans(ptsInCurrCluster, 2, distMeas) sseSplit = sum(splitClustAss[:,1])#compare the SSE to the currrent minimum sseNotSplit = sum(clusterAssment[nonzero(clusterAssment[:,0].A!=i)[0],1]) print "sseSplit, and notSplit: ",sseSplit,sseNotSplit if (sseSplit + sseNotSplit) < lowestSSE: bestCentToSplit = i bestNewCents = centroidMat bestClustAss = splitClustAss.copy() lowestSSE = sseSplit + sseNotSplit bestClustAss[nonzero(bestClustAss[:,0].A == 1)[0],0] = len(centList) #change 1 to 3,4, or whatever bestClustAss[nonzero(bestClustAss[:,0].A == 0)[0],0] = bestCentToSplit print 'the bestCentToSplit is: ',bestCentToSplit print 'the len of bestClustAss is: ', len(bestClustAss) centList[bestCentToSplit] = bestNewCents[0,:].tolist()[0]#replace a centroid with two best centroids centList.append(bestNewCents[1,:].tolist()[0]) clusterAssment[nonzero(clusterAssment[:,0].A == bestCentToSplit)[0],:]= bestClustAss#reassign new clusters, and SSE return mat(centList), clusterAssmentdataMat3 = mat(loadDataSet("testSet2.txt"))centList, myNewAssments = biKmeans(dataMat3,3)
效果
Figure 10-2: 二分k-均值预测结果
10.4 小结
聚类是一种无监督的学习方法。聚类将数据点归到多个簇中,其中相似数据点处于同一簇中,不相似点处于不同簇中。聚类中可以使用多种不同的方法来计算相似度。
在python scipy包中也实现了一些聚类算法,from scipy.cluster.vp import *可以找到kmeans2函数,通过内置函数直接计算聚类的质心,可参考博客http://blog.csdn.net/u010454729/article/details/41158167。
- 《机器学习实战》笔记之十——利用K均值聚类算法对未标注数据分组
- 机器学习实战笔记-利用K均值聚类算法对未标注数据分组
- 机器学习实战 第十章 利用K-均值聚类算法对未标注数据分组
- 机器学习实战-利用K-均值聚类算法对未标注数据分组
- 机器学习之利用K-均值聚类算法对未标注数据分组
- 《机器学习实战》学习笔记-[13]-无监督学习-利用K-均值聚类对未标注数据分组
- 《机器学习实战》学习笔记-[14]-无监督学习-利用二分K-均值聚类对未标注数据分组
- 代码注释:机器学习实战第10章 利用K-均值聚类算法对未标注数据分组
- 机器学习之-用k-均值聚类算法对未标注数据分组-具体怎么实现及应用
- 机器学习之-用k-均值聚类算法对未标注数据分组-具体怎么实现及应用
- 利用K-均值聚类算法对未标注数据分组
- 第十章 利用K-均值聚类算法对未标注数据分组
- 第十章 利用k-均值聚类算法对未标注数据分组
- 第10章 利用K-均值聚类算法对未标注数据分组
- py2.7《机器学习实战》利用k-means聚类算法对未标数据分组
- 三、K-均值聚类算法对未标注的数据分组
- K-均值聚类算法对未标注数据分组(1)
- 机器学习(八):寻找数据的分组——k均值聚类
- 关于保存Activity的instance state
- 遍历所有文件夹,并找出相符的文件
- storm jar包执行报错问题解决
- Linux设置开机等待时间
- iMobiTrax安装
- 《机器学习实战》笔记之十——利用K均值聚类算法对未标注数据分组
- SparseArray
- Linux初学——设置启动载入、建立虚拟内存
- 欢迎使用CSDN-markdown编辑器
- 开发API查询工具
- web测试
- 学生创业,这些问题要解决好
- 解决VS2010连接MySQL出现的问题
- filter不能利用spring注入怎么办?