k-means算法的Python实现

来源:互联网 发布:简单编程软件 编辑:程序博客网 时间:2024/05/18 01:08

数据集为

1.658985    4.285136-3.453687   3.4243214.838138    -1.151539-5.379713   -3.3621040.972564    2.924086-3.567919   1.5316110.450614    -3.302219-3.487105   -1.7244322.668759    1.594842-3.156485   3.1911373.165506    -3.999838-2.786837   -3.0993544.208187    2.984927-2.123337   2.9433660.704199    -0.479481-0.392370   -3.9637042.831667    1.574018-0.790153   3.3431442.943496    -3.357075-3.195883   -2.2839262.336445    2.875106-1.786345   2.5542482.190101    -1.906020-3.403367   -2.7782881.778124    3.880832-1.688346   2.2302672.592976    -2.054368-4.007257   -3.2070662.257734    3.387564-2.679011   0.7851190.939512    -4.023563-3.674424   -2.2610842.046259    2.735279-3.189470   1.7802694.372646    -0.822248-2.579316   -3.4975761.889034    5.190400-0.798747   2.1855882.836520    -2.658556-3.837877   -3.2538152.096701    3.886007-2.709034   2.9238873.367037    -3.184789-2.121479   -4.2325862.329546    3.179764-3.284816   3.2730993.091414    -3.815232-3.762093   -2.4321913.542056    2.778832-1.736822   4.2410412.127073    -2.983680-4.323818   -3.9381163.792121    5.135768-4.786473   3.3585472.624081    -3.260715-4.009299   -2.9781152.493525    1.963710-2.513661   2.6421621.864375    -3.176309-3.171184   -3.5724522.894220    2.489128-2.562539   2.8844383.491078    -3.947487-2.565729   -2.0121143.332948    3.983102-1.616805   3.5731882.280615    -2.559444-2.651229   -3.1031982.321395    3.154987-1.685703   2.9396973.031012    -3.620252-4.599622   -2.1858294.196223    1.126677-2.133863   3.0936864.668892    -2.562705-2.793241   -2.1497062.884105    3.043438-2.967647   2.8486964.479332    -1.764772-4.905566   -2.911070
import numpy as npimport mathdef 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 dataMatdef 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