您的位置:首页 > 其它

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

2018-03-30 15:17 225 查看
这里主要记录对书上相关程序运行结果的一些展示。
程序:# -*- 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可能会收敛到局部最小值,如下图所示:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息