K-Means算法
介绍
K-Means算法是一种常用的聚类算法,也称为K-均值聚类或快速聚类法。K-Means算法将数据划分为预设的K类,以样本点到聚类中心之间的距离作为研究的评价指标,以最小平方误差作为准则函数,迭代至距离平方和趋于稳定且小于某个特定数值或达到指定迭代次数,此时聚类完成。
原理
K-Means算法通过确定每个样本与其聚类中心点的距离的最小值,得出聚类方案的一种算法。研究对象为连续属性时,距离判定方法有欧氏距离、曼哈顿距离、闵可夫斯基距离等,最常用的是欧氏距离;研究对象为文档数据时,常使用余弦相似性度量进行研究。
- 输入N个样本{X1,X2,…,Xn},Xn属于D维欧式几何空间,将类别定为K类;
- 初始化K个样本{Z1,Z2,…,Zk},其中每个样本点都是一个初始聚类中心;
- 以距离初始聚类中心点最近为原则对每个样本进行分类,利用欧式距离,将每个样本点划分到距离其最近的聚类中心所在的簇,计算欧氏距离;
- 计算每个簇的均值,作为新的聚类中心点;
这个循环迭代的目标是使目标函数
最小化,即同一个簇之间差异小,不同簇之间差异大。
求最小化误差平方和:
对SSE求偏导
其中 为第i个簇当中点的个数,即新的聚类中心点就是初始聚类中心点的均值。 - 重复步骤3、4进行迭代直到聚类中心点不变,或者达到指定的迭代次数,此时的聚类情况是我们最终得到的结果。
流程图如下图所示:
应用
我们对下面40组数据进行K-Means聚类分析:
数据
(1.658985,4.285136),(-3.453687,3.424321),(4.838138,-1.151539),(-5.379713,-3.362104),(0.972564,2.924086),(-3.567919,1.531611),(0.450614,-3.302219),(-3.487105 ,-1.724432),(2.668759,1.594842),(-3.156485,3.191137),(3.165506,-3.999838),(-2.786837,-3.099354),(4.208187,2.984927),(-2.123337,2.943366),(0.704199,-0.479481),(-0.39237,-3.963704),(2.831667,1.574018),(-0.790153,3.343144),(2.943496,-3.357075),(-3.195883,-2.283926),(2.336445,2.875106),(-1.786345 ,2.554248),(2.190101,-1.90602),(-3.403367,-2.778288),(1.778124, 3.880832),(-1.688346,2.230267),(2.592976,-2.054368),(-4.007257,-3.207066),(2.257734,3.387564),(-2.679011,0.785119),(0.939512,-4.023563),(-3.674424,-2.261084),(2.046259,2.735279),(-3.18947,1.780269),(4.372646,-0.822248),(-2.579316, -3.497576),(1.889034,5.1904),(-0.798747,2.185588),(2.83652,-2.658556),(-3.837877,-3.253815),(2.096701,3.886007),(-2.709034,2.923887),(3.367037,-3.184789),(-2.121479,-4.232586),(2.329546,3.179764),(-3.284816,3.273099),(3.091414,-3.815232),(-3.762093,-2.432191),(3.542056,2.778832),(-1.736822,4.241041),(2.127073,-2.98368),(-4.323818,-3.938116),(3.792121,5.135768),(-4.786473,3.358547),(2.624081,-3.260715),(-4.009299,-2.978115),(2.493525,1.96371),(-2.513661,2.642162),(1.864375,-3.176309),(-3.171184,-3.572452),(2.89422,2.489128),(-2.562539,2.884438),(3.491078,-3.947487),(-2.565729,-2.012114),(3.332948,3.983102),(-1.616805,3.573188),(2.280615,-2.559444),(-2.651229,-3.103198),(2.321395,3.154987),(-1.685703,2.939697),(3.031012,-3.620252),(-4.599622,-2.185829),(4.196223,1.126677),(-2.133863,3.093686),(4.668892,-2.562705),(-2.793241,-2.149706),(2.884105,3.043438),(-2.967647,2.848696),(4.479332,-1.764772),(-4.905566,-2.91107)
程序:
import numpy as np
import matplotlib.pyplot as plt
加载数据
def loadDataSet(fileName):
data = np.loadtxt(fileName,delimiter=’\t’)
return data
欧氏距离计算
def distEclud(x,y):
return np.sqrt(np.sum((x-y)**2)) # 计算欧氏距离
为给定数据集构建一个包含K个随机质心的集合
def randCent(dataSet,k):
m,n = dataSet.shape
centroids = np.zeros((k,n))
for i in range(k):
index = int(np.random.uniform(0,m)) #
centroids[i,:] = dataSet[index,:]
return centroids
k均值聚类(完整)
def KMeans(dataSet,k):
m = np.shape(dataSet)[0] #行的数目
# 第一列存样本属于哪一簇
# 第二列存样本的到簇的中心点的误差
clusterAssment = np.mat(np.zeros((m,2)))
clusterChange = True
# 第1步 初始化centroids
centroids = randCent(dataSet,k)
while clusterChange:
clusterChange = False
# 遍历所有的样本(行数)
for i in range(m):
minDist = 100000.0
minIndex = -1
# 遍历所有的质心
#第2步 找出最近的质心
for j in range(k):
# 计算该样本到质心的欧式距离
distance = distEclud(centroids[j,:],dataSet[i,:])
if distance < minDist:
minDist = distance
minIndex = j
# 第 3 步:更新每一行样本所属的簇
if clusterAssment[i,0] != minIndex:
clusterChange = True
clusterAssment[i,:] = minIndex,minDist**2
#第 4 步:更新质心
for j in range(k):
pointsInCluster = dataSet[np.nonzero(clusterAssment[:,0].A == j)[0]] # 获取簇类所有的点
centroids[j,:] = np.mean(pointsInCluster,axis=0) # 对矩阵的行求均值
print("Congratulations,cluster complete!")
return centroids,clusterAssment
def showCluster(dataSet,k,centroids,clusterAssment):
m,n = dataSet.shape
if n != 2:
print("数据不是二维的")
return 1
mark = ['or', 'ob', 'og', 'ok', '^r', '+r', 'sr', 'dr', '<r', 'pr']
if k > len(mark):
print("k值太大了")
return 1
# 绘制所有的样本
for i in range(m):
markIndex = int(clusterAssment[i,0])
plt.plot(dataSet[i,0],dataSet[i,1],mark[markIndex])
mark = ['Dr', 'Db', 'Dg', 'Dk', '^b', '+b', 'sb', 'db', '<b', 'pb']
# 绘制质心
for i in range(k):
plt.plot(centroids[i,0],centroids[i,1],mark[i])
plt.show()
dataSet = loadDataSet("data111.txt")
k = 4
centroids,clusterAssment = KMeans(dataSet,k)
showCluster(dataSet,k,centroids,clusterAssment)
print(centroids)
print(clusterAssment)
输出结果:
Congratulations,cluster complete!
聚类中心:
[ 2.80293085 -2.7315146 ]
[-2.46154315 2.78737555]
[-3.38237045 -2.9473363 ]
[ 2.6265299 3.10868015]
类别及与所属簇中心点的距离(分为0、1、2、3四类):
坐 标 所属类别 距中心点最短距离
(1.658985,4.285136) 3 7.76508437
(-3.453687,3.424321) 1 32.62168092
(4.838138,-1.151539) 0 8.14381943
(-5.379713,-3.362104) 2 25.23551276
(0.972564,2.924086) 3 3.06889551
(-3.567919,1.531611) 1 37.38279441
(0.450614,-3.302219) 0 6.51328092
(-3.487105 ,-1.724432) 2 14.59172381
(2.668759,1.594842) 3 2.55232474
(-3.156485,3.191137) 1 29.35235095
(3.165506,-3.999838) 0 0.
(-2.786837,-3.099354) 2 6.48057314
(4.208187,2.984927) 3 3.4532362
(-2.123337,2.943366) 1 19.39109497
(0.704199,-0.479481) 0 11.49864079
(-0.39237,-3.963704) 2 0.
(2.831667,1.574018) 3 2.06212705
(-0.790153,3.343144) 1 9.2915883
(2.943496,-3.357075) 0 0.
(-3.195883,-2.283926) 2 10.68133927
(2.336445,2.875106) 3 6.26146266
(-1.786345 ,2.554248) 1 17.04899051
(2.190101,-1.90602) 0 0.
(-3.403367,-2.778288) 2 10.47131403
(1.778124, 3.880832) 3 5.77462709
(-1.688346,2.230267) 1 16.91088371
(2.592976,-2.054368) 0 0.
(-4.007257,-3.207066) 2 13.63990909
(2.257734,3.387564) 3 2.94220606
(-2.679011,0.785119) 1 11.55448999
(0.939512,-4.023563) 0 5.24624298
(-3.674424,-2.261084) 2 13.67079332
(2.046259,2.735279) 3 2.24969595
(-3.18947,1.780269) 1 32.25542863
(4.372646,-0.822248) 0 7.55594561
(-2.579316, -3.497576) 2 5.00000812
(1.889034,5.1904) 3 11.74755528
(-0.798747,2.185588) 1 10.78682241
(2.83652,-2.658556) 0 0.
(-3.837877,-3.253815) 2 12.37546088
(2.096701,3.886007) 3 4.85160923
(-2.709034,2.923887) 1 24.88378073
(3.367037,-3.184789) 0 0.
(-2.121479,-4.232586) 2 3.06211546
(2.329546,3.179764) 3 2.29808071
(-3.284816,3.273099) 1 30.73296274
(3.091414,-3.815232) 0 0.
(-3.762093,-2.432191) 2 13.70056517
(3.542056,2.778832) 3 3.68513733
(-1.736822,4.241041) 1 16.68490063
(2.127073,-2.98368) 0 0.
(-4.323818,-3.938116) 2 15.45693812
(3.792121,5.135768) 3 18.07739544
(-4.786473,3.358547) 1 49.62169425
(2.624081,-3.260715) 0 0.
(-4.009299,-2.978115) 2 14.05356107
(2.493525,1.96371) 3 3.01190434
(-2.513661,2.642162) 1 23.32183439
(1.864375,-3.176309) 0 0.
(-3.171184,-3.572452) 2 7.87488537
(2.89422,2.489128) 3 3.4935024
(-2.562539,2.884438) 1 23.48816757
(3.491078,-3.947487) 0 0.
(-2.565729,-2.012114) 2 8.53219287
(3.332948,3.983102) 3 9.87170964
(-1.616805,3.573188) 1 15.04650873
(2.280615,-2.559444) 0 0.
(-2.651229,-3.103198) 2 5.84291456
(2.321395,3.154987) 3 2.26399569
(-1.685703,2.939697) 1 15.75128022
(3.031012,-3.620252) 3 7.76508437
(-4.599622,-2.185829) 1 32.62168092
(4.196223,1.126677) 0 8.14381943
(-2.133863,3.093686) 2 25.23551276
(4.668892,-2.562705) 3 3.06889551
(-2.793241,-2.149706) 1 37.38279441
(2.884105,3.043438) 0 6.51328092
(-2.967647,2.848696) 2 14.59172381
(4.479332,-1.764772) 3 2.55232474
(-4.905566,-2.91107) 1 29.35235095