python Kmeans算法

python的多元高斯生成起来好麻烦,所以只好用matlab先生成测试数据然后再进行测试了。cnblogs上面写公式好麻烦,所以就不多写了。上代码吧。

kmeans的基本思想就是通过迭代的方法,更新不同类别的的数据均值,从而达到聚类的目的,因为需要先固定一个均值μiold,然后再通过梯度的方法更新μ值。这就天然的包含了EM的思想。

kmeans对起始的均值设定比较敏感,因此并不能保证最终能够收敛到一个好的结果。而且考虑到它需要计算每个点到中心点的距离,计算复杂度非常高,因此,当数据点非常多,而且聚类数目比较多的时候,就会造成速度非常慢的结果。

#!/usr/bin/env python

import numpy as np
import nose
import random
from matplotlib import pylab

def dist(x,y):
    return np.sqrt(np.sum((x-y)**2))
def distMat(X,Y):
    mat=[]
    for x in X:
        mat.append(map(lambda y:dist(x,y),Y))
    return np.mat(mat)
def sum_dist(data,label,center):
    s=0
    for i in range(data.shape[0]):
        s+=dist(data[i],center[label[i]])
    return s

def kmeans(data,cluster,threshold=1.0e-19,maxIter=100):
    m=len(data)
    labels=np.zeros(m)
    center=np.array(random.sample(data,cluster))
    s=sum_dist(data,labels,center)
    print s
    #iterator times
    n=0
    print center
    while 1:
        n=n+1
        tmp_mat=distMat(data,center)
        labels=tmp_mat.argmin(axis=1)
        color=['r*','w^','y+']
        pylab.hold(False)
        for i in range(cluster):
            idx=(labels==i).nonzero()
            #print "idx is",idx[0]
            #print data[idx[0]]
            center[i]=np.mean(data[idx[0]],axis=1)
            #center[i]=data[idx[0]].mean(axis=0)
            d_i=data[idx[0]]
            d_i=d_i[0] 
            #print 'd_i',d_i[0:-1,0]
            pylab.plot(d_i[0:-1,0],d_i[0:-1,1],color[i])
            pylab.hold(True)
            print 'center[i] ',center[i][0]
            pylab.scatter(center[i][0],center[i][1],s=1000,marker='.',c='r')
        pylab.show()
        s1=sum_dist(data,labels,center)
        print s1
        if s-s1<=threshold:
            break
        s=s1
        if n>maxIter:
            break
    print n
    return center
import scipy.io as si
if __name__=='__main__':
    data=si.loadmat('a.mat')
    data=data['a']
    center=kmeans(data,3)
    print center

 

posted on 2013-03-13 10:56  long0x0  阅读(4454)  评论(0编辑  收藏  举报

导航