K-means聚类(博客聚类)

继上一篇博客使用分级聚类对博客进行聚类《集体智慧编程》,本次使用K-means方法来对博客聚类,部分代码和数据请看上一篇

K-均值聚类应该算是比较容易理解的一种算法了,我在前面学习的时候有专门的说过K-means的原理原理和实现,如果不是很理解可以可以去看看。

作者使用方法和我之前的大同小异,我用的是多个组合函数对二维数据集的聚类,更容易理解和实现。本次的数据集为多维的数据集,方法也略有不同,所以这里记录一下,下面看代码:

(这里只写了K-means的代码,其余调用的函数代码和数据在上一篇中,可以直接拿来用)

import random

def kcluster(rows,distance=pearson,k=4):
	#确定每个点的最小值和最大值 (这里竖着求出每个关键字出现次数的最小最大值)
	ranges= [(min([row[i] for row in rows]),max([row[i] for row in rows]))
	for i in range(len(rows[0]))]

	#随机创建k个中心点 [[],[],[],[]]
	clusters = [[random.random()*(ranges[i][1]-ranges[i][0]) + ranges[i][0]
	for i in range(len(rows[0]))] for j in range(k)]

	lastmatches = None	#记录上一次聚类后的结果,用来和本次相比
	cnt = 0
	while(1):
		cnt +=1
		print('Iteration {}'.format(cnt))
		bestmatches = [[] for i in range(k)]	#生成k个嵌套的列表

		#寻找每一行距离最近的中心点,然后添加到中心点列表中
		for j in range(len(rows)):
			row = rows[j]
			bestmatch = 0		#每次用来记录该点目前所在最优簇号
			for i in range(k):				#与k个中心点比较,选出最近的
				d = distance(clusters[i],row)
				if(d<distance(clusters[bestmatch],row)):
					bestmatch = i
			bestmatches[bestmatch].append(j)

		#如果结果与上一次相同,则整个过程结束
		if(bestmatches == lastmatches):
			break
		lastmatches = bestmatches

		#把中心点移到其所有成员的平均位置处
		for i in range(k):
			avgs = [0.0]*len(rows[0])	#初始化所有关键字那么长的列表
			if(len(bestmatches[i]) > 0):
				for rowid in bestmatches[i]:			#这两个for循环求第i簇中所有列表点的和	每个列表对应相加
					for m in range(len(rows[rowid])):
						avgs[m] +=rows[rowid][m]

				for j in range(len(avgs)):				#该for循环将第i簇的和的列表除以i簇长度 求平均值
					avgs[j] /=len(bestmatches[i])
				clusters[i] = avgs
	return bestmatches

kclust = kcluster(data,k=10)
print(kclust)
result1 = [blognames[r] for r in kclust[0]]
print(result1)
result2 = [blognames[r] for r in kclust[1]]
print(result2)

相对与我前面写的K-means,作者的方法代码更优化了,所以还是值得看的。

看一下结果:

这里只打印了0、1两个簇,我们的算法将它们聚在了一起,说明它们之间一定有着相似的关系,这里我们先不研究了。

这里其实可以发现,这几次的算法,大多用到了第一章学习的相似度距离的计算方法,这些算法得以实现,都通过了对距离的判断,所以对于相似度距离计算的方法应该有比较牢固的的掌握。

猜你喜欢

转载自blog.csdn.net/qq_36523839/article/details/81119695