K-Means
来源:互联网 发布:网络策略 sftp 协议 编辑:程序博客网 时间:2024/05/16 00:31
K-均值聚类算法
优点:容易实现,不足之处可能收敛到局部最小值,在大规模数据集上收敛较慢,适用于数值型数据。工作流程如下:
创建k个点作为起始质心(经常是随机选择)
当任意一个点的簇分配结果发生改变时
对数据集中的每个数据点
对每个质心
计算质心与数据点之间的距离
将数据点分配到距其最近的簇
>>> from numpy import *
>>> datMat=mat(kmeans.loadDataSet('E:/code/testSet.txt'))
>>> min(datMat[:,0])
matrix([[-5.379713]])
>>> min(datMat[:,1])
matrix([[-4.232586]])
>>> max(datMat[:,1])
matrix([[ 5.1904]])
>>> max(datMat[:,0])
matrix([[ 4.838138]])
<module 'kmeans' from 'E:\python\kmeans.py'>
>>> datMat=mat(kmeans.loadDataSet('E:/code/testSet.txt'))
>>> myCenttroids,clustAssing=kmeans.keans(datMat,4)
[[-2.70314932 2.01452543]
[ 0.89843689 2.61822779]
[ 1.18644542 -3.90997013]
[ 3.1300084 -2.7441036 ]]
[[-3.07195136 0.92565029]
[ 2.24547378 2.92273278]
[-2.00155638 -3.472942 ]
[ 3.25624481 -2.728045 ]]
[[-2.54951105 2.75812458]
[ 2.46383071 3.1198451 ]
[-3.19984738 -2.96423548]
[ 2.926737 -2.70147753]]
[[-2.46154315 2.78737555]
[ 2.6265299 3.10868015]
[-3.38237045 -2.9473363 ]
[ 2.80293085 -2.7315146 ]]
<module 'kmeans' from 'E:\python\kmeans.py'>
>>> datMat3=mat(kmeans.loadDataSet('E:/code/testSet2.txt'))
>>> centList,myNewAssments=kmeans.biKmeans(datMat3,3)
[]
Traceback (most recent call last):
File "<pyshell#40>", line 1, in <module>
centList,myNewAssments=kmeans.biKmeans(datMat3,3)
File "E:\python\kmeans.py", line 65, in biKmeans
centroidMat,splitClustAss=kMeans(ptsInCurrCluster,2,distMeas)#k-均值算法会生成两个质心,同时给出误差值
File "E:\python\kmeans.py", line 31, in kMeans
centroids=createCent(dataSet,k)
File "E:\python\kmeans.py", line 24, in randCent
rangeJ=float(max(dataSet[:,j])-minJ)
ValueError: max() arg is an empty sequence
优点:容易实现,不足之处可能收敛到局部最小值,在大规模数据集上收敛较慢,适用于数值型数据。工作流程如下:
创建k个点作为起始质心(经常是随机选择)
当任意一个点的簇分配结果发生改变时
对数据集中的每个数据点
对每个质心
计算质心与数据点之间的距离
将数据点分配到距其最近的簇
对每一个簇,计算簇中所有点的均值并将均值作为质心
#-*- coding:utf-8 -*-from numpy import *def loadDataSet(fileName): dataMat=[] fr=open(fileName) for line in fr.readlines(): curLine=line.strip().split('\t') fitLine=map(float,curLine) dataMat.append(fitLine) return dataMat#计算两个向量的欧氏距离def distEclud(vecA,vecB): return sqrt(sum(power(vecA-vecB,2)))#给定数据集构建一个包含k个随机质心的集合def randCent(dataSet,k): n=shape(dataSet)[1] centroids=mat(zeros((k,n))) #随机质心必须要在整个数据集的边界之内,通过找到每一维最小和最大值完成 for j in range(n): minJ=min(dataSet[:,j]) rangeJ=float(max(dataSet[:,j])-minJ) centroids[:,j]=minJ+rangeJ*random.rand(k,1)#生成0到1.0之间的随机数并通过取值范围和最小值确保随机点在数据边界之内 return centroids>>> import kmeans
>>> from numpy import *
>>> datMat=mat(kmeans.loadDataSet('E:/code/testSet.txt'))
>>> min(datMat[:,0])
matrix([[-5.379713]])
>>> min(datMat[:,1])
matrix([[-4.232586]])
>>> max(datMat[:,1])
matrix([[ 5.1904]])
>>> max(datMat[:,0])
matrix([[ 4.838138]])
>>> kmeans.randCent(datMat,2)
matrix([[ 1.58043495, -1.31447897],
[ 1.70103927, 4.95529564]])
测试一下距离的计算方法:
>>> kmeans.distEclud(datMat[0],datMat[1])
5.184632816681332
所支持的函数正常运行,准备实现K均值算法。创建k个质心,然后将每个点分配到最近的质心,在重新计算质心。重复数次,直到数据点的簇分配结果不会改变为止。
#数据集及簇的数目是必选参数,计算距离和创建初始质心的函数可选def keans(dataSet,k,distMeas=distEclud,createCent=randCent): m=shape(dataSet)[0]#创建一个矩阵来存储每个点的簇分配结果 clusterAssment=mat(zeros((m,2)))#一列记录簇索引值,一列存储误差 centroids=createCent(dataSet,k) clusterChanged=True#标识变量,true则继续迭代 #遍历所有数据找到距离每个点最近的质心,对每个点遍历所有质心并计算每个质心的距离来完成 while clusterChanged: clusterChanged=False for i in range(m): minDist=inf;minIndex=-1 for j in range(k): distJI=distMeas(centroids[j,:],dataSet[i,:]) if distJI<minDist: minDist=distJI;minIndex=j if clusterAssment[i,0]!=minIndex:clusterChanged=True clusterAssment[i,:]=minIndex,minDist**2 print centroids #遍历并更新取值,通过数组过滤来获得给定簇的所有点,计算均值,axis=0表示沿矩阵列的方向进行均值计算 for cent in range(k): ptsInClust=dataSet[nonzero(clusterAssment[:,0].A==cent)[0]] centroids[cent,:]=mean(ptsInClust,axis=0) return centroids,clusterAssment>>> reload(kmeans)
<module 'kmeans' from 'E:\python\kmeans.py'>
>>> datMat=mat(kmeans.loadDataSet('E:/code/testSet.txt'))
>>> myCenttroids,clustAssing=kmeans.keans(datMat,4)
[[-2.70314932 2.01452543]
[ 0.89843689 2.61822779]
[ 1.18644542 -3.90997013]
[ 3.1300084 -2.7441036 ]]
[[-3.07195136 0.92565029]
[ 2.24547378 2.92273278]
[-2.00155638 -3.472942 ]
[ 3.25624481 -2.728045 ]]
[[-2.54951105 2.75812458]
[ 2.46383071 3.1198451 ]
[-3.19984738 -2.96423548]
[ 2.926737 -2.70147753]]
[[-2.46154315 2.78737555]
[ 2.6265299 3.10868015]
[-3.38237045 -2.9473363 ]
[ 2.80293085 -2.7315146 ]]
二分K-均值算法:
将所有点看成一个簇
当簇数目小于k时
对于每一个簇
计算总误差
在给定的簇上面进行K-均值聚类(k=2)
计算将该簇一分为二之后的总误差
选择使得误差最小的那个簇进行划分操作
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#将最小SSE设置为无穷大 #尝试划分每一簇 for i in range(len(centList)): ptsInCurrCluster=dataSet[nonzero(clusterAssment[:,0].A!=i)[0],:]#小数据集 centroidMat,splitClustAss=kMeans(ptsInCurrCluster,2,distMeas)#k-均值算法会生成两个质心,同时给出误差值 sseSplit=sum(splitClustAss[:,1]) sseNotSplit=sum(clusterAssment[nonzero(clusterAssment[:,0].A!=i)[0],1]) print "sseSplit,and not Split:",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) 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,:]#新的簇结果被更新 centList.append(bestNewCents[1,:]) clusterAssment[nonzero(clusterAssment[:,0].A==bestCentToSplit)[0],:]=bestClustAss return mat(centList),clusterAssment>>> reload(kmeans)
<module 'kmeans' from 'E:\python\kmeans.py'>
>>> datMat3=mat(kmeans.loadDataSet('E:/code/testSet2.txt'))
>>> centList,myNewAssments=kmeans.biKmeans(datMat3,3)
[]
Traceback (most recent call last):
File "<pyshell#40>", line 1, in <module>
centList,myNewAssments=kmeans.biKmeans(datMat3,3)
File "E:\python\kmeans.py", line 65, in biKmeans
centroidMat,splitClustAss=kMeans(ptsInCurrCluster,2,distMeas)#k-均值算法会生成两个质心,同时给出误差值
File "E:\python\kmeans.py", line 31, in kMeans
centroids=createCent(dataSet,k)
File "E:\python\kmeans.py", line 24, in randCent
rangeJ=float(max(dataSet[:,j])-minJ)
ValueError: max() arg is an empty sequence
为什么出错呢?试了好几种方法,求大神指点,多谢!
0 0
- K-Means
- k-means
- K-means
- k means
- K-means
- K-means
- K-Means
- k-means
- k-means
- k-means
- k-means
- k-means
- k-means
- K-means ++
- k-means
- k-Means
- K-means
- K-Means
- storm模型
- SQL高级语句-SQL UNIQUE 约束,唯一标识数据库表中的每条记录。
- html框架之iframe和frame及frameset的相关属性介绍
- 【OpenCV】笔记(4) ——自带UI显示
- allegro 通孔焊盘制作
- K-Means
- 让机器人更安全——(2.协作机器人的兴起)
- 浅析SurfaceView使用surfaceview制作你想要的动画
- Android 检测服务是否开启的方法
- CodeForces 712 C. Memory and De-Evolution(贪心)
- 百度杯二月Reverse场Project的writeup
- 支付宝接口实现
- 80题题目+AC代码汇总 ~ 南阳 NYOJ
- RecyclerView的简单使用--------------(一)