K-means算法实现
"""
Created on Tue Apr 27 21:20:07 2021
@author: ***
"""
from numpy import *
from math import *
import csv
def dist(A,B):
return sqrt(sum(power(A-B,2)))
def createR(dataMat,k):
n=shape(dataMat)[1]
center = mat(zeros((k,n)))
for j in range(n):
minj = min(dataMat[:,j])
maxj = max(dataMat[:,j])
rangej =float(maxj-minj)
print(maxj)
center[:,j] = mat(minj + rangej*(random.rand(k,1)))
return center
def Kmeans(dataMat,k,distF=dist,createF=createR):
m = shape(dataMat)[0]
cluster = mat(zeros((m,2)))
center = createF(dataMat,k)
print(center)
flag = True
while flag:
flag = False
for i in range(m):
mind = float('inf')
minj = -1
for j in range(k):
d = distF(dataMat[i,:],center[j,:])
if d < mind:
mind = d
minj = j
if cluster[i,0] != minj:
cluster[i,:] = minj,mind
flag = True
for centj in range(k):
ss=dataMat[nonzero(cluster[:,0]==centj)[0]]
center[centj,:] = mean(ss,axis=0)
return center,cluster
def bitKmeans(dataSet,k,distF=dist):
m = shape(dataSet)[0]
cluster = mat(zeros((m,2)))
center0 = mean(dataSet,axis=0).tolist()[0]
centerL = [center0]
for j in range(m):
cluster[j,1] = distF(mat(center0),dataSet[j,:])**2
while (len(centerL)<k) :
lowEss = float('inf')
for i in range(len(centerL)):
indata = dataSet[nonzero(cluster[:,0]==i)[0],:]
if indata.size==0:
continue
centerM,clusterM = Kmeans(indata,2)
inlowEss = sum(clusterM[:,1])
outlowEss = sum(cluster[nonzero(cluster[:,0]!=i)[0],1])
if (inlowEss+outlowEss) < lowEss:
lowEss = inlowEss + outlowEss
bestCenter = i
bestcluster = clusterM.copy()
bestCenters = centerM
bestcluster[nonzero(bestcluster[:,0]==0)[0],0] = bestCenter
bestcluster[nonzero(bestcluster[:,0]==1)[0],0] = len(centerL)
centerL[bestCenter] = bestCenters[0,:].tolist()[0]
centerL.append(bestCenters[1,:].tolist()[0])
cluster[nonzero(cluster[:,0]==bestCenter)[0],:] = bestcluster
return mat(centerL),cluster
datas=[]
with open('BuddyMove.csv') as f:
data = csv.reader(f)
for row in data:
arow = list(map(float,row))
datas.append(arow)
dat = mat(datas)
[center,cluster]=bitKmeans(dat[:,1:3],6)
print(transpose(cluster)[0,:])