k-Means算法(Machine Learning in Action)基于python3.6

K-均值算法首先随机确定k个初始点作为质心,为每个点找距其最近的质心,并将分配给质心所对应的簇,然后每个簇的质心更新为该簇所有点的平均值。

优点:容易实现

缺点:可能收敛到局部最小值,在大规模数据集上收敛较慢

适用数据类型:数值型数据


 1 '''
 2     创建k个点作为起始质心(经常是随机选择)
 3     当任意一个点的簇分配结果发生改变时
 4         对数据集中的每个数据点
 5             对每个质心
 6                 计算质心与数据点之间的距离
 7             将数据点分配到距其最近的簇
 8         对每一个簇,计算簇中所有点的均值并将均值作为质心
 9 '''
10 from numpy import *
11 #读取文本文件到一个列表中
12 def loadDataSet(filename):
13     dataMat=[]
14     fr = open(filename)
15     for line in fr.readlines():
16         curline = line.strip().split('\t')
17         fltline = list(map(float,curline))
18         dataMat.append(fltline)
19     return dataMat
20 
21 #求欧式距离
22 def distEclud(vecA, vecB):
23     return sqrt(sum(power(vecA - vecB, 2)))
24 
25 #构建簇质心
26 def randCent(dataSet, k):
27     n = shape(dataSet)[1]#列表列数
28     centroids = mat(zeros((k,n)))
29     for j in range(n):
30         minJ = min(dataSet[:,j])#第j列的最小值
31         maxJ = max(dataSet[:,j])#第j列的最大值
32         rangeJ = float(maxJ - minJ)#第j列的变化范围
33         centroids[:,j] = mat(minJ + rangeJ * random.rand(k,1))#生成在边界内的随机数
34     return centroids
35 
36 datMat = mat(loadDataSet('testSet.txt'))
37 ''' test----------------------------------------
38 print(min(datMat[:,0]))
39 print(min(datMat[:,1]))
40 print(max(datMat[:,0]))
41 print(max(datMat[:,1]))
42 print(randCent(datMat, 2))
43 print(distEclud(datMat[0], datMat[1]))
44 
45 '''
46 '''
47     core code:
48     计算质心-分配-重新计算
49 '''
50 #分别是数据集,聚类类数,距离函数,创建初始质心函数)
51 def kMeans(dataSet, k, distMeas=distEclud, createCent=randCent):
52     m = shape(dataSet)[0]#行数
53     result = mat(zeros((m,2)))#结果矩阵,一列记录簇索引值,一列记录存储误差(当前点到簇质心的距离)
54     centroids = createCent(dataSet, k)#簇质心
55     changed = True#标志变量,如果为True,继续迭代,若任一点簇分配结果发生变化,更新changed
56     while changed:
57         changed = False
58         for i in range(m):
59             minDist = inf#正负无穷
60             minIndex = -1
61             #寻找最近的质心
62             for j in range(k):
63                 distJI = distMeas(centroids[j,:],dataSet[i,:])#算点到每一个质心的距离
64                 if distJI < minDist:
65                     minDist = distJI; minIndex = j
66             if result[i,0] != minIndex: changed = True#如果更新后的结果矩阵簇索引值与原来的不同,标志位置为True
67             result[i,:] = minIndex,minDist ** 2#结果矩阵此时这一行第一列为点到质心距离最小的那一个质心,第二列为距离的平方
68         #更新质心的位置
69         print(centroids)
70         for cent in range(k):
71             ptsInClust = dataSet[nonzero(result[:,0].A == cent)[0]]#.A变成数组,获取给定簇的所有点
72             centroids[cent,:] = mean(ptsInClust, axis = 0)#按列方向求均值
73     return centroids, result
74 
75 # test------------------------------------------------
76 myCentroids, result = kMeans(datMat,4)
77 print(myCentroids)
78 print('\n')
79 print(result)

 


 

posted @ 2018-04-25 17:41  抹茶奶绿不加冰  阅读(370)  评论(0编辑  收藏  举报