机器学习(Stanford)笔记-(K-means)

           监督式学习的训练集是带label的,比如下图中的圈圈和叉叉,分别代表“正”数据集和“负”数据集,监督式学习的目标是找到一个可以分开这两个数据集的decision boundary。

 

        相反,非监督式学习的训练集是没有带任何标签的。如下图所示,数据集是没有带任何标签,需要非监督式学习算法找到训练数据集的近似点,将相似的对象归到同一个聚类中。其中一种就是聚类算法。

        K-means算法一个典型的聚类算法,将相似的数据对象归到同一簇中,将不相似的对象归到不同簇中。

        K-means算法流程大概如下,随机选取K个初始点作为聚类中心,遍历每个点,寻找其与最近的聚类中心,并将该点分配到该聚类中心所在的簇。接着,分别计算每个簇的平均值,更新k个聚类中心。K-means算法演示如下:


K-means算法的伪代码:


        没有明显区分的簇群的数据,K-means算法也可以很好地将数据分开,如下图所示的体重和身高数据集,利用K-means算法根据这些数据集将T恤的大小分为三类,S,M,L。

K-means 的目标优化函数cost function 是基于最小误差平方和准则。



        其中μc(i)代表与x(i)最近的聚类中心点。优化目标是试图找到c(1),c(2),...,c(m)和μ12,...,μk使得目标函数最小。直观来说,就是各簇的数据越相似,与该簇的聚类中心的距离就越小,数据跟聚类中心的误差平方越小。

       在上面的 K-means伪代码中,第一步是随机初始化K个聚类中心。如何随机初始化?首先保证K<m,即聚类中心的个数K要小于训练数据集m。然后随机抽取训练集的K个数据作为聚类中心。

       由于聚类中心是随机选取的,如下图所示,如果随机选取的好,那么数据的聚类效果就很好,但如果随机选取的不好,那可能结果并不是我们想要的。


为了避免这种情况,通常采取的策略是多次运行K-means算法,选取优化目标函数最小的情况作为最后结果。算法的伪代码如下。

       由于K-means算法的K的值是必须预先设定的,如何设定K值,第一种方法可以根据不同K值算出优化目标函数值,画出K-J曲线,选取拐点的那个K值。


        如果没有出现拐点,那就根据具体聚类的目的来选取,比如对衣服尺码进行聚类分析,如果你把尺码定为S,M,L,那K就选3;如果你把尺码定为XS,S,M,L,XL,那K选取5。

K-means代码是从zouxy09参考过来的,做了一些稍微的修改

import pdb
from numpy import *
import time
import matplotlib.pyplot as plt

# show your cluster only available with 2-D data
def showCluster(dataSet, k, centroids, clusterAssment):
	numSamples, dim = dataSet.shape
	if dim != 2:
		print "Sorry! I can not draw because the dimension of your data is not 2!"
		return 1

	mark = ['or', 'ob', 'og', 'ok', '^r', '+r', 'sr', 'dr', '<r', 'pr']
	if k > len(mark):
		print "Sorry! Your k is too large! please contact Zouxy"
		return 1

	# draw all samples
	for i in xrange(numSamples):
		markIndex = int(clusterAssment[i, 0])
		plt.plot(dataSet[i, 0], dataSet[i, 1], mark[markIndex])

	mark = ['Dr', 'Db', 'Dg', 'Dk', '^b', '+b', 'sb', 'db', '<b', 'pb']
	# draw the centroids
	for i in range(k):
		plt.plot(centroids[i, 0], centroids[i, 1], mark[i], markersize = 12)

	plt.show()

	
# calculate Euclidean distance
def euclDistance(vector1, vector2):
	return sqrt(sum(power(vector2 - vector1, 2)))

# init centroids with random samples
def initCentroids(dataSet, k):
	numSamples, dim = dataSet.shape
	centroids = zeros((k, dim))
	for i in range(k):
		index = int(random.uniform(0, numSamples))
		centroids[i, :] = dataSet[index, :]
	return centroids

# k-means cluster
def kmeans(dataSet, k):
	numSamples = dataSet.shape[0]
	# first column stores which cluster this sample belongs to,
	# second column stores the error between this sample and its centroid
	clusterAssment = mat(zeros((numSamples, 2)))
	clusterChanged = True

	## step 1: init centroids
	centroids = initCentroids(dataSet, k)
	showCluster(dataSet, k, centroids, clusterAssment)
	##pdb.set_trace()
	
	while clusterChanged:
		clusterChanged = False
		## for each sample
		for i in xrange(numSamples):
			minDist  = 100000.0
			minIndex = 0
			## for each centroid
			## step 2: find the centroid who is closest
			for j in range(k):
				distance = euclDistance(centroids[j, :], dataSet[i, :])
				if distance < minDist:
					minDist  = distance
					minIndex = j
			
			## step 3: update its cluster
			if clusterAssment[i, 0] != minIndex:
				clusterChanged = True
				clusterAssment[i, :] = minIndex, minDist**2

		## step 4: update centroids
		for j in range(k):
			pointsInCluster = dataSet[nonzero(clusterAssment[:, 0].A == j)[0]]
			centroids[j, :] = mean(pointsInCluster, axis = 0)
		showCluster(dataSet, k, centroids, clusterAssment)
		
		   
	print 'Congratulations, cluster complete!'
	return centroids, clusterAssment



if __name__ == '__main__':
    ## step 1: load data  
    print "step 1: load data..."  
    dataSet = []  
    fileIn = open('C://Python27/test/testSet.txt')  
    for line in fileIn.readlines():  
        lineArr = line.strip().split('\t')  
        dataSet.append([float(lineArr[0]), float(lineArr[1])])
        
    #pdb.set_trace()
    ## step 2: clustering...  
    print "step 2: clustering..."  
    dataSet = mat(dataSet)  
    k = 4  
    centroids, clusterAssment = kmeans(dataSet, k)  
  
    ## step 3: show the result  
    print "step 3: show the result..."  
    showCluster(dataSet, k, centroids, clusterAssment)  
                    
    







参考资料

1、http://www.ryanzhang.info/archives/1213 

2、http://blog.csdn.net/zouxy09/article/details/17589329

3、https://class.coursera.org/ml-007

4、《Machine Learning in Action》  

5、http://coolshell.cn/articles/7779.html

6、http://www.cnblogs.com/leoo2sk/archive/2010/09/20/k-means.html

7、http://blog.pluskid.org/?page_id=78漫谈 Clustering 系列很赞的博文


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值