K-means 聚类

K-means 聚类主要内容

·K-means算法

·python程序实现

一.K-means算法(基于划分的聚类方法)

1.构造n个对象数据库D的划分, 将其划分成k个聚类
2.启发式方法: k-平均值(k- means)和 k-中心点(k- medoids) 算法
k-平均值(MacQueen’67): 每个簇用该簇中对象的平均值来表示
k-中心点或 PAM (Partition around medoids) (Kaufman & Rousseeuw’87): 每个簇用接近聚类中心的一个对象来表示
3.这些启发式算法适合发现中小规模数据库中的球状聚类
4.对于大规模数据库和处理任意形状的聚类,这些算法需要进一步扩展
5.优点:容易实现;缺点:可能收敛到局部最小,在大规模数据上收敛速度慢;适用数据类型:数字型数据。

二.python程序实现

伪代码表示如下:

创建k个点作为初始的质心点(随机选择) 
当任意一个点的簇分配结果发生改变时 
            对数据集中的每一个数据点 
                        对每一个质心 
                              计算质心与数据点的距离 
                        将数据点分配到距离最近的簇 
           对每一个簇,计算簇中所有点的均值,并将均值作为质心

程序清单10-1 K-均值聚类支持函数

from numpy import *

def loadDataSet(fileName):      #读取文件
    dataMat = []                #保持数据数据的列表
    fr = open(fileName)         #打开文件
    for line in fr.readlines(): #以行的方式读取
        curLine = line.strip().split(',') #strip()是删除line的空格,split(',')按分隔符为“,”分割
        fltLine = map(float,curLine) #map接收一个函数和一个可迭代对象(如列表)作为参数
        dataMat.append(fltLine) #把所有行连接在一起
    return dataMat

def distEclud(vecA, vecB):#计算向量vecA和向量vecB的欧式距离
    return sqrt(sum(power(vecA - vecB, 2))) #power向量vecA和向量vecB的差求次方,sum求和,sqrt开根号。

def randCent(dataSet, k):
    n = shape(dataSet)[1]
    centroids = mat(zeros((k,n)))#创建k*n的数组
    for j in range(n):#列循环
        minJ = min(dataSet[:,j]) #列的最小值
        rangeJ = float(max(dataSet[:,j]) - minJ)#列的最大值与最小值的差值
        centroids[:,j] = mat(minJ + rangeJ * random.rand(k,1))#最小值加差值的随机值
    return centroids

程序清单10-2 K-均值聚类算法
输入:dataSet聚类结果矩阵;distEclud欧式距离;k类数;distMeas=distEclud欧式距离;createCent=randCent聚类结果

def kMeans(dataSet, k, distMeas=distEclud, createCent=randCent):
    m = shape(dataSet)[0]
    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[j,:],dataSet[i,:])#求距离
                if distJI < minDist:                          #如果原始数据的第i行与聚类数据的第j行的距离小于
                    minDist = distJI; minIndex = j            #最小距离
            if clusterAssment[i,0] != minIndex: clusterChanged = True 
            clusterAssment[i,:] = minIndex,minDist**2         #更新给原始数据的组类并保存该最小距离                            
        for cent in range(k):#找出各类数据,求均值
            ptsInClust = dataSet[nonzero(clusterAssment[:,0].A==cent)[0]]
            #nonzero是逻辑函数,clusterAssment[:,0].A==cent转化出和类数cent相同的逻辑数,取原始数据的这些行
            #保存在ptsInClust矩阵里。
            centroids[cent,:] = mean(ptsInClust, axis=0) #求均值并保存在结果矩阵里 
          print centroids                                #本次更新的结果,
    return centroids, clusterAssment

def showCluster(dataSet, k, centroids,clusterAssment):
    mark = ['Dr', 'Db', 'Dg', 'Dk', '^b', '+b', 'sb', 'db', '<b', 'pb']
    numSamples, dim = dataSet.shape
    for i in range(numSamples):
        markIndex = int(clusterAssment[i, 0])
        plt.plot(dataSet[i, 0], dataSet[i, 1], mark[markIndex])
    for i in range(k):
        plt.plot(centroids[i, 0], centroids[i, 1], mark[i], markersize = 12)
    plt.show()

程序清单10-3 K-均值聚类算法主程序测试

import kMeans
from numpy import *
import matplotlib.pyplot as plt
from pandas import Series, DataFrame
import pandas as pd

datMat=mat(kMeans.loadDataSet('testSet.txt'))
myCentroids,clustAssing=kMeans.kMeans(datMat,4)
centroids,clusterAssment=kMeans.kMeans(datMat,4)
kMeans.showCluster(datMat,4,centroids,clusterAssment)

测试结果
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值