#-*- coding:utf-8 -*- import numpy as np def kmeas(x,k,maxIt):#将数据导入处理并找好随机k中心点 numpoints,numDim=x.shape dataset=np.zeros((numpoints,numDim+1)) dataset[:,:-1]=x#将x的都赋给dataset的除了最后一列 centroids=dataset[np.random.randint(numpoints,size=k),:]#随机产生k个中心点 centroids=dataset[0:2,:]#在0到2中随机产生中心点 centroids[:,-1]=range(1,k+1)#初始化最后一行 iterations=0 oldcentroids=None while not shouldStop(oldcentroids,centroids,iterations,maxIt): print("iterations:\n",iterations) print("dataset:\n",dataset) print("centroids:",centroids) oldcentroids=np.copy(centroids)#copy就是产生相同的但是 下次变化一个互不影响 iterations+=1 updatellabels(dataset,centroids) centroids=getcentroids(dataset,k) return dataset def shouldStop(oldcentroids,centroids,iterations,maxIt):#判断循环次数或者中心点有变化来停止 if iterations>maxIt: return True return np.array_equal(oldcentroids,centroids)#equal自动把我们比较2个值是否一样一样返回true def updatellabels(dataset,centroids):#划分每个点到中心点的距离以此分类为哪个类 numpoints,nunDims=dataset.shape for i in range(0,numpoints): dataset[i,-1]=getlabelfromclosestcentroid(dataset[i,:-1],centroids) def getlabelfromclosestcentroid(datasetrow,centroids):#比较每个点到中心点的距离 label=centroids[0,-1] minDist=np.linalg.norm(datasetrow-centroids[0,:-1])#每个点到中心点的距离最小值 for i in range(1,centroids.shape[0]): dist=np.linalg.norm(datasetrow-centroids[i,:-1]) if dist<minDist:#如果小于最小距离将他赋予哪一类 minDist=dist label=centroids[i,-1]#将改行点化为这一类 print("minDist:",minDist) return label def getcentroids(dataset,k):#更新中心点 result=np.zeros((k,dataset.shape[1])) for i in range(1,k+1): onecluster=dataset[dataset[:,-1]==i,:-1]#取出一类中的点 result[i-1,:-1]=np.mean(onecluster,axis=0)#按列求平均值 result[i-1,-1]=i return result x1=np.array([1,1]) x2=np.array([2,1]) x3=np.array([4,3]) x4=np.array([5,4]) textx=np.vstack((x1,x2,x3,x4)) result=kmeas(textx,2,10) print("final result:",result)
简单的kmeans算法解析
最新推荐文章于 2023-01-04 16:18:44 发布