最近在接触python,看到K-Means算法,于是在网上查找了一下实现方法,看了一个C语言实现,觉得利用python更好实现,而且可以很方便的数据可视化,于是自己编了一个小程序,顺便练习python基础知识,本人初学者还请指出不足之处。
(本例中数据摘自网上C语言实现的程序)
#-*- coding: utf-8 -*-
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
global K
global N
global center
global mean
#分簇数量
K=3
#样本数量
N=11
#样本列表
point=[(2.0,10.0),(2.0,5.0),(8.0,4.0),(5.0,8.0),(7.0,5.0),(6.0,4.0),(1.0,2.0),(4.0,9.0),(7.0,3.0),(1.0,3.0),(3.0,9.0)]
center=[]#纪录每个点归属哪个簇
mean=[]#每个簇的中心点
#计算两个点之间的距离
def getDistance(p1,p2):
return ((p1[0]-p2[0])**2+(p1[1]-p2[1])**2)**(1/2)
#计算每个簇的中心点
def getMean(center):
print(center)
print(len(center))
for i in range(len(center)):
sum_x=0
sum_y=0
for j in range(len(center[i])):
sum_x+=center[i][j][0]
sum_y+=center[i][j][1]
mean[i]=(sum_x/len(center[i]),sum_y/len(center[i]))
print('第',i,'个簇的中心点是:',mean[i])
#计算平方误差
def getE():
sum_E=0
for i in range(len(center)):
for j in range(len(center[i])):
sum_E+=(center[i][j][0]-mean[i][0])**2+(center[i][j][1]-mean[i][1])**2
return sum_E
#对每个点进行聚类
def cluster():
global center
center=[]
for i in range(K):
center.append([])
for i in range(N):
min_clu=999999999.0
flag=-1
for j in range(K):
n=(point[i][0]-mean[j][0])**2+(point[i][1]-mean[j][1])**2
if(min_clu>n):
min_clu=n
flag=j
center[flag].append(point[i])
for i in range(K):
print('第',i,'簇:',center[i])
#输出数据样本
print(point)
#初始化中心点
mean=[point[0],point[3],point[6]]
#n为聚类次数
n=0
#第一次聚类
cluster();
temp1=getE();
n+=1
print('第',n,'次聚类的平方误差:',temp1)
#重新生成中心点
getMean(center)
#第二次聚类
cluster()
temp2=getE()
n+=1
print('第',n,'次聚类的平方误差:',temp2)
#判断连续两次聚类的平方误差是否相同,相同则结束,否则继续
while(temp1!=temp2):
temp1=temp2
getMean(center)
cluster();
temp2=getE();
n+=1
print('第',n,'次聚类的平方误差:',temp2)
#数据样本横坐标列表
xx=[]
for i in range(K):
xx.append([])
#数据样本纵坐标样本
yy=[]
for i in range(K):
yy.append([])
#填充横纵坐标 并绘制散点图
for q in range(K):
for i in range(len(center[q])):
xx[q].append(center[q][i][0])
for i in range(len(center[q])):
yy[q].append(center[q][i][1])
plt.scatter(xx[q],yy[q])
plt.scatter(mean[q][0],mean[q][1])
#显示散点图
plt.show()
散点图效果如下:
各个簇的点分别用不同颜色标注,每个簇的中心点也与其他点颜色不同
控制台输出结果: