k-means算法是一种聚类算法,所谓聚类,即根据相似性原则,将具有较高相似度的数据对象划分至同一类簇,将具有较高相异度的数据对象划分至不同类簇。
聚类与分类最大的区别在于,聚类过程为无监督过程,即待处理数据对象没有任何先验知识,而分类过程为有监督过程。
k-means是最简单的聚类算法之一,应用十分广泛,k代表类簇个数,means代表类簇内数据对象的均值。
k-means以距离作为相似性的评价指标,其基本思想是按照样本之间的距离将样本聚成不同的簇,两个样本的距离越近,其相似度就越大,则它们越有可能在同一个类簇,从而得到独立的簇作为聚类目标。
样本数据对象间距离的计算有很多种,k-means算法通常采用欧氏距离来计算数据对象间的距离。
具体算法流程 参见:https://blog.csdn.net/mrharvey/article/details/18085163
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
size = 30 ##取值范围
##计算欧式距离
def distEuclid(x,y):
return np.sqrt(np.sum((x-y)**2))
##随机产生n个dim维度的数据 (这里为了展示结果 dim取2或者3)
def genDataset(n,dim):
data = []
while len(data)<n:
p = np.around(np.random.rand(dim)*size,decimals=2)
data.append(p)
return data
## 初始化簇中心点 一开始随机从样本中选择k个 当做各类簇的中心
def initCentroid(data,k):
num,dim = data.shape
centpoint = np.zeros((k,dim))
l = [x for x in range(num)]
np.random.shuffle(l)
for i in range(k):
index = int(l[i])
centpoint[i] = data[index]
return centpoint
##进行KMeans分类
def KMeans(data,k):
##样本个数
num = np.shape(data)[0]
##记录各样本 簇信息 0:属于哪个簇 1:距离该簇中心点距离
cluster = np.zeros((num,2))
cluster[:,0]=-1
##记录是否有样本改变簇分类
change = True
##初始化各簇中心点
cp = initCentroid(data,k)
while change:
change = False
##遍历每一个样本
for i in range(num):
minDist = 9999.9
minIndex = -1
##计算该样本距离每一个簇中心点的距离 找到距离最近的中心点
for j in range(k):
dis = distEuclid(cp[j],data[i])
if dis < minDist:
minDist = dis
minIndex = j
##如果找到的簇中心点非当前簇 则改变该样本的簇分类
if cluster[i,0]!=minIndex:
change = True
cluster[i,:] = minIndex,minDist
## 根据样本重新分类 计算新的簇中心点
for j in range(k):
pointincluster = data[[x for x in range(num) if cluster[x,0]==j]]
cp[j] = np.mean(pointincluster,axis=0)
print("finish!")
return cp,cluster
##展示结果 各类簇使用不同的颜色 中心点使用X表示
def Show(data,k,cp,cluster):
num,dim = data.shape
color = ['r','g','b','c','y','m','k']
##二维图
if dim==2:
for i in range(num):
mark = int(cluster[i,0])
plt.plot(data[i,0],data[i,1],color[mark]+'o')
for i in range(k):
plt.plot(cp[i,0],cp[i,1],color[i]+'x')
##三维图
elif dim==3:
ax = plt.subplot(111,projection ='3d')
for i in range(num):
mark = int(cluster[i,0])
ax.scatter(data[i,0],data[i,1],data[i,2],c=color[mark])
for i in range(k):
ax.scatter(cp[i,0],cp[i,1],cp[i,2],c=color[i],marker='x')
plt.show()
num = 50 ##点个数
k=4 ##分类个数
data = np.array(genDataset(num,3))
cp,cluster = KMeans(data,k)
Show(data,k,cp,cluster)