• Kemans算法及其Python 实现


    算法优缺点:

    优点:容易实现
    缺点:可能收敛到局部最小值,在大规模数据集上收敛较慢
    使用数据类型:数值型数据

    算法思想

    k-means算法实际上就是通过计算不同样本间的距离来判断他们的相近关系的,相近的就会放到同一个类别中去。

    1.首先我们需要选择一个k值,也就是我们希望把数据分成多少类,这里k值的选择对结果的影响很大,Ng的课说的选择方法有两种一种是elbow method,简单的说就是根据聚类的结果和k的函数关系判断k为多少的时候效果最好。另一种则是根据具体的需求确定,比如说进行衬衫尺寸的聚类你可能就会考虑分成三类(L,M,S)等

    2.然后我们需要选择最初的聚类点(或者叫质心),这里的选择一般是随机选择的,代码中的是在数据范围内随机选择,另一种是随机选择数据中的点。这些点的选择会很大程度上影响到最终的结果,也就是说运气不好的话就到局部最小值去了。而且该算法对非球状簇的分类比较差。这里有两种处理方法,一种是多次取均值,另一种则是后面的改进算法(bisecting K-means)

    3.终于我们开始进入正题了,接下来我们会把数据集中所有的点都计算下与这些质心的距离,把它们分到离它们质心最近的那一类中去。完成后我们则需要将每个簇算出平均值,用这个点作为新的质心。反复重复这两步,直到收敛我们就得到了最终的结果。

    函数

    loadDataSet(fileName)
    从文件中读取数据集
    distEclud(vecA, vecB)
    计算距离,这里用的是欧氏距离,当然其他合理的距离都是可以的
    randCent(dataSet, k)
    随机生成初始的质心,这里是虽具选取数据范围内的点
    kMeans(dataSet, k, distMeas=distEclud, createCent=randCent)
    kmeans算法,输入数据和k值。后面两个事可选的距离计算方式和初始质心的选择方式
    show(dataSet, k, centroids, clusterAssment)
    可视化结果

    #coding=utf-8
    from numpy import *
    
    def loadDataSet(fileName):
        dataMat = []
        fr = open(fileName)
        for line in fr.readlines():
            curLine = line.strip().split('	')
            fltLine = map(float, curLine)
            dataMat.append(fltLine)
        return dataMat
        
    #计算两个向量的距离,用的是欧几里得距离
    def distEclud(vecA, vecB):
        return sqrt(sum(power(vecA - vecB, 2)))
    
    #随机生成初始的质心(ng的课说的初始方式是随机选K个点)    
    def randCent(dataSet, k):
        n = shape(dataSet)[1]
        centroids = mat(zeros((k,n)))
        for j in range(n):
            minJ = min(dataSet[:,j])
            rangeJ = float(max(array(dataSet)[:,j]) - minJ)
            centroids[:,j] = minJ + rangeJ * random.rand(k,1)
        return centroids
        
    def kMeans(dataSet, k, distMeas=distEclud, createCent=randCent):
        m = shape(dataSet)[0]
        clusterAssment = mat(zeros((m,2)))#create mat to assign data points 
                                          #to a centroid, also holds SE of each point
        centroids = createCent(dataSet, k)
        clusterChanged = True
        while clusterChanged:
            clusterChanged = False
            for i in range(m):#for each data point assign it to the closest centroid
                minDist = inf
                minIndex = -1
                for j in range(k):
                    distJI = distMeas(centroids[j,:],dataSet[i,:])
                    if distJI < minDist:
                        minDist = distJI; minIndex = j
                if clusterAssment[i,0] != minIndex: 
                    clusterChanged = True
                clusterAssment[i,:] = minIndex,minDist**2
            print centroids
            for cent in range(k):#recalculate centroids
                ptsInClust = dataSet[nonzero(clusterAssment[:,0].A==cent)[0]]#get all the point in this cluster
                centroids[cent,:] = mean(ptsInClust, axis=0) #assign centroid to mean 
        return centroids, clusterAssment
        
    def show(dataSet, k, centroids, clusterAssment):
        from matplotlib import pyplot as plt  
        numSamples, dim = dataSet.shape  
        mark = ['or', 'ob', 'og', 'ok', '^r', '+r', 'sr', 'dr', '<r', 'pr']  
        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']  
        for i in range(k):  
            plt.plot(centroids[i, 0], centroids[i, 1], mark[i], markersize = 12)  
        plt.show()
          
    def main():
        dataMat = mat(loadDataSet('testSet.txt'))
        myCentroids, clustAssing= kMeans(dataMat,4)
        print myCentroids
        show(dataMat, 4, myCentroids, clustAssing)  
        
        
    if __name__ == '__main__':
        main()

    参考链接:http://www.cnblogs.com/MrLJC/p/4127553.html

  • 相关阅读:
    js中属性点.和中括号[]的关系。
    jQuery中的$(window).load()与$(document).ready()以及jquery $(document).ready() 与window.onload的区别
    今天中了一个脚本病毒。把我的所有 html 加了 vbs 脚本,WriteData 是什么鬼?
    原生js 当前时间 倒计时代码
    一看就懂得移动端rem布局、rem如何换算
    使用CSS实现三栏自适应布局(两边宽度固定,中间自适应)
    js运算符的一些特殊应用
    中文目录对 sublime text 有什么影响?
    Spring的注解@Qualifier小结
    伪共享(False Sharing)
  • 原文地址:https://www.cnblogs.com/zhusleep/p/5310418.html
Copyright © 2020-2023  润新知