K-Means Algorithm(K-均值算法)

来源:互联网 发布:如何在淘宝店铺加客服 编辑:程序博客网 时间:2024/06/10 04:42

K-Means algorithms(K-均值)

K-means算是一个很简单的聚类算法,而聚类与决策树、SVM等不同,是一种无监督的学习,所谓无监督学习(Unsupervised learning)是和监督学习相对应的,不同于监督学习,无监督学习所给的训练集是不包含标签的,所有数据集都只包括特征xi而没有标签yi
聚类的主要目的就是将这些没有标签的数据分为N个簇(cluster),其主要的应用有市场划分、社交网络分析、天文学中的数据分析等等。

K-Means的描述如下:

这里写图片描述

先对参数进行说明:

  • x(i)为第i个数据点;
  • c(i)x(i)的簇;
  • uj为第j个簇的质心点;

在对算法进行说明:

  • 首先需要初始化质心点,在K-Means中,通常采用随机的方法对质心点进行初始化。更好的办法是:随机选择m(m>k)个数据,再从中选择k个数据点作为质心点;
  • 第一个for循环主要用于给数据点x(i)赋值c(i),称为 cluster assignment steps,对每一个数据点,都会计算她与所有质心点的距离,而后将数据点分配到与它距离最近的簇;
  • 第二个for循环主要用于更新质心点的位置,称为move centroid steps,而uj这里的计算公式所代表的意思就是,分母:统计所有ci=j的点的个数;分子就ushi所有ci=j的点的坐标和。那整体的意思就很明确了,就是求这些点的平均值,作为新的质心点的位置。

cu收敛之后,就可以结束整个迭代过程。下面看一个实例:
这里写图片描述


优化目标

在上一部分中,我们说最终的目的是要达到一个收敛,那我们就用一个失真函数(distortion function)来衡量。

这里写图片描述

J(c,u)实际上是一个单调递减的函数,且是一个非凸函数,只要我们能找到拐点,那我们就已经达到了收敛,又称这种方法为elbow function
偶尔也有可能陷入局部最优情况,或出现震荡情况,这样一定是了问题了,


总结

K-Means虽然简单,容易实现,但是也会收敛到局部最小值,这种情况下可以采用K-Means的改进算法:二分K-均值算法。算法的思想就是:首先将所有点做为一个簇,然后将该簇一分为二。之后选择其中一个簇进行继续划分,选择哪一个簇进行划分则取决于对其划分是否可以最大程度降低SSE的值,不断划分直到达到用户所指定的K值。


Python的实现

#! /usr/bin/env python# -*-coding:utf8 -*-from numpy import *def loadDataSet(fileName):    dataMat = []    fr = open(fileName)    for line in fr.readlines():        curLine = line.strip().split('/t')        fltLine = map(float, curLine)        dataMat.append(fltLine)    return dataMatdef 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 centroidsdef kMeans(dataSet, k, distMeas = distEclud, createCent = randCent):    # 确定数据集的大小    m = shape(dataSet)[0]    # 建立矩阵来存储c(i)和x(i)距离u(c(i))的值    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 = distMeas(centroids[k, :], 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):            ptsInClust = dataSet[nonzero(clusterAssment[:, 0].A == cent)[0]]            centroids[cent, :] = mean(ptsInClust, axis=0)        return centroids, clusterAssment
0 0
原创粉丝点击