def kMeans(dataSet, k, distMeans =distEclud, createCent = randCent):
#randCent(dataSet, k)随机生成初始的质心,这里是随机选取数据集内的k个点 #distEclud(vecA, vecB)计算距离,这里用的是欧氏距离,当然其他合理的距离都是可以的
m = shape(dataSet)[0] #计算数据集的行数 clusterAssment = mat(zeros((m,2))) #评价簇矩阵m行两列,第一列存所属的簇序号,第二列存该点到该簇质点的距离的平方 分配样本到最近的簇:存[簇序号,距离的平方] 用于存放该样本属于哪类及质心距离 ,mat()即将二维数组转化为m行2列矩阵 # 建立簇分配结果矩阵,第一列存索引,第二列存误差 # clusterAssment第一列存放该数据所属的中心点,第二列是该数据到中心点的距离 centroids = createCent(dataSet, k)#从数据集中随机选取k个点构建k行N列质心矩阵 clusterChanged = True # 用来判断聚类是否已经收敛 while clusterChanged: clusterChanged = False; for i in range(m): # 把每一个数据点划分到离它最近的中心点 minDist = inf; minIndex = -1; # inf表示无穷大量,-inf表示负无穷大量 for j in range(k): distJI = distMeans(centroids[j,:], dataSet[i,:])#计算每个样本与k个中心点的距离 if distJI < minDist: minDist = distJI; minIndex = j #簇序号即按序递增的j #设置两个变量,分别存放数据点到质心的距离, 及数据点属于哪个质心如果第i个数据点到第j个中心点更近,则将i归属为j即获取最小距离,及对应的簇序号if clusterAssment[i,0] != minIndex:
clusterChanged = True; # 如果分配发生变化,则需要继续迭代
clusterAssment[i,:] = minIndex,minDist**2 # 并将第i个数据点的分配情况存入字典 分配样本到最近的簇 print centroids for cent in range(k): # 重新计算中心点 ptsInClust = dataSet[nonzero(clusterAssment[:,0].A == cent)[0]] # 取第一列等于cent的所有列,获取该簇所有的样本点 centroids[cent,:] = mean(ptsInClust, axis = 0) # 算出这些数据的中心点 #更新聚类中心:axis=0沿列方向求均值 return centroids, clusterAssment # --------------------测试---------------------------------------------------- # 用测试数据及测试kmeans算法 datMat = mat(loadDataSet('testSet.txt')) myCentroids,clustAssing = kMeans(datMat,4) print myCentroidsprint clustAssing
对给定的数据集进行聚类
本案例采用二维数据集,共80个样本,有4个类。
如下图所示:
具体算法步骤可参考http://www.cnblogs.com/zhzhang/p/5437778.html