您的位置:首页 > 编程语言 > Python开发

k-means算法的Python实现

2017-06-06 18:38 393 查看
数据集为

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.392370   -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.906020
-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.189470   1.780269
4.372646    -0.822248
-2.579316   -3.497576
1.889034    5.190400
-0.798747   2.185588
2.836520    -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.983680
-4.323818   -3.938116
3.792121    5.135768
-4.786473   3.358547
2.624081    -3.260715
-4.009299   -2.978115
2.493525    1.963710
-2.513661   2.642162
1.864375    -3.176309
-3.171184   -3.572452
2.894220    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.911070


import numpy as np
import math
def loadData(filename):
dataMat = [] #创建一个能装数据的list
fr = open(filename)
for  line in fr.readlines():
curline = line.strip().split('\t')#删除每行最后的换行,以中间的tab分割数据
fltline = list(map(float,curline))
dataMat.append(fltline)
dataMat = np.mat(dataMat) #将datMat集合编程ndarray类型存放
return dataMat

def disEclud(vecA, vecB):
return np.sqrt(np.sum(np.power(vecA - vecB,2))) #计算欧氏距离

def randCent(dataSet,k):#创建随机初始质心
n = np.shape(dataSet)[1] #取得列数
centroids = np.mat(np.zeros((k,n)))#创建一个 K行 n列的0矩阵
for j in range(n):#一列一列的进行随机选取初始化
minJ = np.min().dataset[:,j] #取第J列的最小值
rangeJ = float(np.max(dataSet[:,j]) - minJ) #取最大最小值的差
centroids[:,j] = np.mat(minJ + rangeJ * np.random.rand(k,1)) #创建一个K行1列的向量添加到centroids的第J列上
return centroids

def kMeans(dataset,k,disMeas = distEclud, createCent = randCent):
m = np.shape(dataset)[0] #取行数
clusterAssment = np.mat(np.zero((m,2))) #创建一个M行2列的0矩阵 该矩阵用来存dataset中每个点属于哪个簇,第二列是到质心的距离
centroids = createCent(dataset,k)
clusterChanged = True
while clusterChanged:
clusterChanged = False
for  i in range(m):
minDist = math.inf #minDist初始化为无穷大
minIndex = -1 #
for  j in range(k):
distJI = disMeas(centroids[j,:],dataset[i,:])#计算 dataset中每个点和质心的距离
if distJI < minDist:
minDist = distJI
minIndex = j
if clusterAssment[i,0] != minIndex:
clusterChanged = True
clusterAssment[i,:] = minIndex, minDist **2 #将距离最近的点和这个点到质心的距离的平方存入clusterAssment
for cent in range(k):
ptsInClust = dataset[np.nonzeros(clusterAssment[:,0].A == cent)[0]]
#np.nonzeros(clusterAssment[:,0].A == cent)[0]这句代码的意思是 取clusterAssment第1列的值 .A 返回的是matrix object 让其与现在的类型对比,如果相等
#返回clusterAssment的第一列
#dataset把符合条件的样本存入ptsInClust中
centroids[cent,:] = np.mean(prsInClust, axis = 0)
#重新计算质心,也就是求各个列的均值。axis= 0 表示列。
return centroids, clusterAssment
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: