机器学习实战--k-均值聚类

一、聚类是一种无监督学习,他讲类似的对象放到同一簇下,有点像自动分类。聚类方法几乎能够用到任何对象上,簇内的对象越类似,聚类结果就越好。算法

二、K均值聚类的优势数组

  算法简单容易实现app

  缺点:dom

  可能收敛到局部最小值,在大规模数据上收敛速度较慢ide

三、K-均值算法算法流程以及伪代码性能

  首先随机选择k个初始点做为质心。而后将数据集中的每一个点分配到一个簇中,具体来讲,遍历数据集计算数据与质心之间的距离找到最小的距离将该数据划分到该簇内,完成后更新簇的质心。可是只要有数据点的簇发生变化就须要继续进行划分,直到没有点发生改变。学习

  伪代码:spa

  建立K个点做为起始质心(常常是随机选择,可是不能越界,下面的代码有具体的作法)code

  当任意一个点的簇分配结果发生变化时对象

    对数据集中的每个数据点

      对每一个质心

        计算质心与数据点的距离

      将数据点分配到距离最近的簇

    对于每个簇,计算簇中全部点的均值并将均值做为质心

  

from numpy import *

def loadDataSet(filename):
    dataMat=[]
    fr = open(filename)
    for line in fr.readlines():
        curLine = line.strip().split('\t')
        fltLine = list(map(float, curLine))
        #print(fltLine)
        dataMat.append(fltLine)
    return dataMat


def distEclud(vecA, vecB):
    return sqrt(sum(power(vecA - vecB, 2)))

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(dataSet[:, j]) - minJ)
        centroids[:,j] = minJ + rangeJ * random.rand(k, 1)
    return centroids


def Kmeans(dataSet, k, distMeans = distEclud, createCent = randCent):
    m = shape(dataSet)[0]
    #创建一个m*2的矩阵位置0记录聚类的索引,位置1记录到聚类质心的距离
    clusterAssment = mat(zeros((m,2)))
    centroids = createCent(dataSet, k)
    clusterChanged = True
    while clusterChanged:
        clusterChanged = False
        for i in range(m):
            minDist = inf; minIndex = -1
            for j in range(k):
                distJI = distMeans(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):
            #经过数组过滤来得到给定簇的全部样本,nozero返回一个0/1矩阵,而后取第一列的索引列
            ptsInClust = dataSet[nonzero(clusterAssment[:, 0].A == cent)[0]]
            centroids[cent, :] = mean(ptsInClust, axis = 0)
    return centroids, clusterAssment
#print(loadDataSet('testSet.txt'))
dataMat = mat(loadDataSet('testSet.txt'))
myCentroids, clustAssing = Kmeans(dataMat, 4)
print(myCentroids)
print(clustAssing)
K-均值算法

四、使用后处理提升聚类的性能

  K均值算法中的K是用户给出的,如何衡量在给定K个聚类的状况下聚类的性能。对于K均值算法可能会收敛到局部最小,而不能收敛到全局最小,所以可能聚类效果很差。在上边的代码中clusterAssment保存了每一个数据点的簇标号以及点到簇质心的偏差(就是距离)。那么可使用SSE(sum of squared Erro,偏差平方和)做为衡量聚类性能的指标,SSE的数值越小就表示数据点越接近他们的质心聚类效果也就越好,同时因为对偏差取了平方因此越远的点在SSE中就越受重视。

  怎么下降SSE?一种简单的方法是增长簇的数量,可是这样很差啊,你是去聚类了你弄了和数据集同样的簇,那还聚个啥。所以须要在不改变簇的数目的前提降低低SSE。一种可行的办法是选择SSE最大的簇,而后对其继续进行K均值算法。同时为了保证簇的数目不变,能够将簇与簇进行合并。

  合并的方法:质心之间距离最近的合并;合并两个簇而后计算总的SSE,合并可使SSE最小的簇。

五、二分 K均值算法

  为了克服K均值算法收敛于局部最小的问题,有人提出了一个二分K均值的算法。回来继续

相关文章
相关标签/搜索