【机器学习实战】10.k-means聚类算法(1)

这里主要记录对书上相关程序运行结果的一些展示。

程序:

# -*- coding: utf-8 -*-
"""
Created on Fri Mar 30 10:42:00 2018

@author: ##
"""

from numpy import *
import matplotlib.pyplot as plt 

def loadDataSet(filename):
    '''
    导入数据
    '''
    dataMat=[]
    fr=open(filename)
    for line in fr.readlines():
        curLine=line.strip().split('\t')
        #fltLine=map(float,curLine)  #python2里返回列表,python3里返回迭代器
        fitLine=[float(subLine) for subLine in curLine]
        dataMat.append(fitLine)
    return dataMat

def distEclude(vecA,vecB):
    '''
    量化误差指标,两向量的欧氏距离
    '''
    return sqrt(sum(power(vecA-vecB,2)))   
        
def randCent(dataSet,k):
    '''
    构建包含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,distMeas=distEclude,createCent=randCent):
    '''
    kmeans主体算法
    
    '''
    m=shape(dataSet)[0]
    clusterAssment=mat(zeros((m,2)))
    centroids=createCent(dataSet,k)  #随机选择质心
    clusterChanged=True
    g=0
    while clusterChanged:
        clusterChanged=False
        g+=1
        for i in range(m):
            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(g)
        print(centroids)     
        plotFig(dataSet,clusterAssment,centroids)
        '''
        #更新质心的位置
        clusterAssment[:,0].A 返回基于矩阵的数组,得到各样本点所属的质心标号
        nonzero(clusterAssment[:,0].A==cent)[0] 得到质心为cent的样本标号
        '''
        for cent in range(k):
            ptsInClust=dataSet[nonzero(clusterAssment[:,0].A==cent)[0]]
            centroids[cent,:]=mean(ptsInClust,axis=0)  #在列方向上进行均值计算
        
    return centroids,clusterAssment

def plotFig(dataSet,clusterAssment,centroids):
    k=shape(centroids)[0]
    plt.scatter(centroids[:,0].A,centroids[:,1].A,s=70,c='black',marker='+')
    for i in range(k):
        ptsInClust=dataSet[nonzero(clusterAssment[:,0].A==i)[0]]
        plt.scatter(ptsInClust[:,0].A,ptsInClust[:,1].A,s=20)    
    plt.show()
    

if __name__=='__main__':
    dataMat=mat(loadDataSet('testSet.txt'))
    #查看数据点
    plt.scatter(dataMat[:,0].A,dataMat[:,1].A)
    plt.show()    
    #这里质心数量设为4    
    myCentroids,clusterAssing=kMeans(dataMat,4)
    #print(myCentroids)
    plotFig(dataMat,clusterAssing,myCentroids)

运行结果:

通过查看数据集的散点图,确定簇个数为4,具体数据分布情况为:


程序运行后,得到聚类结果如下图所示(黑色标记的为质心):


其各质心在迭代时的移动情况如下图所示:


但是k-means可能会收敛到局部最小值,如下图所示:



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值