K-means聚类算法
具体步骤
具体代码
import random
import matplotlib.pylab as plt
#产生随机50个点
#这里产生数据并保存数据,不然每次数据总变来变去的,要是代码写得不当,也不太方便查看
def producte_data():
f = open("data.csv","w")
for i in range(50):
a = random.randint(1,10)
b = random.randint(1,10)
f.write(str(a)+','+str(b)+'\n')
f.close()
def read_data(): #读取数据
f = open("data.csv")
lines = f.readlines()
f.close()
L = []
for line in lines:
line = line.strip('\n').split(',')
l = [eval(i) for i in line]
L.append(l)
return L#所有点
def random_data(L,K):#随机产生中心点
random.seed(250)
C = []
i = 0
while i<K:
c = random.choice(L) #随机选择三个点
i = i+1
if c not in C: #如果产生一样的随机点
C.append(c)
else:
i = i-1
return C#中心点
def sort_data(L,C,n): #分类
dic = {} #[坐标,属于类]
for line in L:
D = []
for i in range(len(C)):
d = ((line[0]-C[i][0])**2+(line[1]-C[i][1])**2)**0.5
D.append((d,tuple(C[i]))) #tuple(C[i])想作为字典的键,键不可变
near = min(D) #选出最近的点
if near[1] not in dic:
dic[near[1]] = [line]
else:
value = dic[near[1]] #点分类
value.append(line)
dic[near[1]] = value
#算中心距离,寻找新的中心点
new_L = []
for i in dic.items():
if n == 0:
sx = 0
sy = 0
coun = 0
else:
sx = i[0][0]
sy = i[0][1]
coun = 1 #数这一类点的个数,方便再次产生新的中心点
for j in i[1]:
coun = coun+1
sx = sx+j[0]
sy = sy+j[1]
sx = sx/coun
sy = sy/coun
new_L.append([sx,sy])
return new_L,dic
def draw(dic):
color = ['pink','blue','green','black','purple','yellow','lightgrey']
i = 0
for value in dic.items():
c = color[i]
plt.scatter(value[0][0], value[0][1], color=c,s=len(value[1])*10) #聚类中心的点
for v in value[1]:
plt.scatter(v[0], v[1], color=c)
i = i+1
plt.title("Sorting position")
plt.show()
def draw_begin(L):#展示初始状态的点的分布
for value in L:
plt.scatter(value[0],value[1],color = 'black')
plt.title("Starting position")
plt.show()
producte_data() #随机产生数据集
L = read_data() #L为所有点
draw_begin(L)
K = eval(input("请输入想要将这些点分为类的个数:"))
C = random_data(L,K)#C为中心点
n = 0
new_L,dic = sort_data(L,C,n)
while(n<100): #限定条件1迭代次数为100
for i in range(K):
d = ((L[i][0]-new_L[i][0])**2+(L[i][1]-new_L[i][1])**2)**0.5
if d >1: #限定条件2 新的聚类中心和之间的聚类中心误差小于1
n = n+1
new_L,dic = sort_data(L,new_L,n)
if d <1:
n = 101
draw(dic)
效果图
K=3
K=5
因为数据是随机产生的,如果不保持数据文件,每次产生的效果都不同哦。