聚类算法(一):k-均值 (k-means)算法

时间:2021-10-22 23:04:11

首先确保你在动手写代码之前已经了解什么是聚类分析。

k-均值算法----一种基于形心地技术的聚类算法。k-均值算法的英文名是k-means,那么这个算法是怎么工作的呢?

k-均值算法把簇的形心定义为簇内点的均值。它的处理流程如下:1.在数据点集D中随机的选择k个对象(这个k表示你要讲数据集分成几个簇),每个对象代表一个簇的初始均值或中心。2.对剩下的每个对象,根据其与哥哥簇中心的欧氏距离,将它分配到最相似的簇。3.k-均值算法迭代的改善内变差。对于每个簇,它使用上次迭代分配到该簇的对象,计算新的均值。 4.使用更新的均值作为新的簇中心。重新分配所有对象。 5.迭代继续,直到分配稳定,本轮行程的簇的中心点坐标与前一轮行程的簇相同。


算法:k-均值

输入:k:簇的数目

   D:包含n个对象的数据集

输出:k个簇的集合

方法:

1.从D中任意选择k个对象作为初始簇中心;

2.repeat

3. 根据簇中对象的均值,将每个对象分配到最相似的簇;

4.  更新簇的均值,即重新计算每个簇中对象的均值;

5.until 不再发生变化



源码(Python)

__author__ = 'ChiXu_15s103144_HIT'

import random
import math

def K_means(data, k):
center = []
cluster = []
dis = []
demo_cluster = []
flag = 0
i = 0
len_data = len(data)
while i<k:
cluster.append(data[random.randint(0, len_data-1)]) #在数据中随机的找点放进cluster中
if cluster in center:
cluster = []
continue
else:
center.append(cluster) #起始状态,每个簇里只有一个随机点
cluster = []
i += 1

while True:
new_cluster = []
for i in xrange(len_data):
for j in xrange(k): #分别计算它与k个中心点的距离
lenth = Distance(data[i],center[j][0])
dis.append(lenth)
#选出距离最短的中心点,并放进center中
dis_copy = dis
min_dis = sorted(dis)[0]
if min_dis == 0:
dis = []
dis_copy = []
continue
else:
mark = dis_copy.index(min_dis)
center[mark].append(data[i])
dis = []
dis_copy = []
#计算每个cluster中的平均中心点
for i in xrange(k):
new_cluster.append(Cluster_Average(center[i]))
for i in xrange(k):
if new_cluster[i] == center[i][0]:
flag += 1
if flag == k: #如果簇内的平均中心点不再发生变化,则return
return center
else: #否则用新的平均中心点取代原来的平均中心点
flag = 0
center = []
for i in xrange(k):
#center.append(new_cluster[i])
demo_cluster.append(new_cluster[i])
center.append(demo_cluster)
demo_cluster = []

def Cluster_Average(cluster): #计算cluster内平均中心点
average = []
total_x = total_y = 0
len_cluster = len(cluster)
for i in xrange(len_cluster):
total_x += cluster[i][0]
total_y += cluster[i][1]
average.append(total_x/len_cluster)
average.append(total_y/len_cluster)
return average

def Distance(point1, point2): #计算两点欧氏距离
if point1 == point2:
return 0
else:
dis_x = point2[0] - point1[0]
dis_y = point2[1] - point1[1]
dis = math.sqrt(dis_x**2 + dis_y**2)
return dis

point = []
data = []
num = raw_input('请输入随机点阵的数目:')
for i in xrange(int(num)): #构造随机点阵
point.append(random.randint(1,100))
point.append(random.randint(1,100))
data.append(point)
point = []
k = raw_input('请输入中心点k的数目:')
center = K_means(data,int(k))
print(center)