K-means算法实现:Python
'''
Created on 2018年4月29日
#K-means算法
@author: shylock
'''
import numpy as np
#X:数据集 k:聚类个数 maxIt:最大迭代次数
def Kmeans(X,k,maxIt):
#获取数据集的行列数
numPoints,numDim = X.shape
#重新构造数据集和,对其进行初始化分类 numDim 加1
dataSet = np.zeros((numPoints,numDim + 1))
#将X数据集的数据放到dataSet中
dataSet[:,:-1] = X
print("dataSet:\n",dataSet)
print("-------------")
#在给定的样本中随机选取中心点 从numPoints行里面随机选取两行,--注意不要重复
#centroids = dataSet[np.random.randint(numPoints,size = k),:]
centroids = dataSet[:2,:]
#在选取的两个中心点中设定他们的类别 从1到k k个
#centroids[:,-1] = np.random.randint(1,k+1,size = k)
centroids[:,-1] = range(1,k+1)
print("centroids:\n",centroids)
print("-------------")
iterations = 0
oldCentroids = None
while not shouldStop(oldCentroids, centroids, iterations, maxIt):
#将最新的中心点的坐标付给oldCentroids
oldCentroids = np.copy(centroids)
iterations += 1
#更新样本的最近中心点 讲dataSet传进函数进行修改
updateLabels(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)
#更新每个样本点的标签
def updateLabels(dataSet,centroids):
numPoints,numDim = dataSet.shape
for i in range(0,numPoints):
dataSet[i,-1] = getLabelFromClosestCentroid(dataSet[i,:-1],centroids)
#传入两个向量求出,一个是样本值对应的向量,一个是中心点的坐标向量,求出他们的欧式距离(x1,y1) , [(cx1,cy1),(cx2,cy2)]
def getLabelFromClosestCentroid(dataSetLow,centroids):
#初始化label并赋予初始值
label = centroids[0,-1]
#初始化最小的距离
minDist = np.linalg.norm(dataSetLow - centroids[0,:-1])
for i in range(1,centroids.shape[0]):
dist = np.linalg.norm(dataSetLow - centroids[i,:-1])
if dist < minDist:
minDist = dist
label = centroids[i,-1]
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]
# print(oneCluster)
# print("--------------")
#计算平均值,求出了样本的中心点 axis = 0:对行求平均值 axis = 0压缩行 axis = 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])
testX = np.vstack((x1,x2,x3,x4))
result = Kmeans(testX,2,10)
print(result)