Kmeans算法和代码实现

一、简介
K-means算法的思想就是对空间K个点为中心进行聚类,对靠近他们的对象进行归类,通过迭代的方法,逐次更新聚类中心(质心)的值,直到得到最好的聚类结果。K-means过程:
1.首先选择k个类别的中心点
2.对任意一个样本,求其到各类中心的距离,将该样本归到距离最短的中心所在的类
3.聚好类后,重新计算每个聚类的中心点位置
4.重复2,3步骤迭代,直到k个类中心点的位置不变,或者达到一定的迭代次数,则迭代结束,否则继续迭代

二、个人知识背景补充
1.数组:
https://baike.baidu.com/item/%E6%95%B0%E7%BB%84/3794097?fr=aladdin

2.nonzero:
https://blog.csdn.net/u013698770/article/details/54632047

np.nonzero函数是numpy中用于得到数组array中非零元素的位置(数组索引)的函数,就是行下标组和列下标组

#代码似乎没对整齐。第一次整这个,以后注意

import numpy as np
#读取数据,变成list,存取数据
def loadDataSet(fileName):
    dataMat=[]
    fr=open(fileName)
    for line in fr.readlines():
        curLine=line.strip.split('\t')
        fltLine=map(float,curLine)     #map内置函数,返回一个list
        dataMat.append(fltLiene)
    return dataMat

#定义欧式距离
def distEclud(vecA,vecB):
    return np.sqrt(np.sum(np.power(vecA-vecB,2)))  #都是返回了一个对象,这个是超级简化的写法了

#找k个随机中心点的坐标
def randcent(dataSet,k):
    n=np.shape(dataSet)[1]
    centroids=np.mat(np.zeros((k,n)))#生成3x2矩阵,用于存储三个中心点的坐标
    for j in range(n):
        minJ=min(dataset[:,j])
        rangeJ=float(max(dataSet[:,j])-minJ)
        array2=minJ+rangeJ*np.random.rand(k,1)#生成k行1列的随机数,位于[0,1]之间
        centroids[:,j]=np.mat(array2)
    return centroids  #返回三个中心点的坐标

def KMeans(dataSet,k,distMeas=distEclud,createCent=randCent):
    m=np.shape(dataSet)[0]
    clusterAssement=np.mat(np.zeros((m,2)))#注意这里是两个小括号
    centroids=creatCent(dataSet,k)#点是你随机生成的那个,不要只会抄。。。。
    clusterChanged=True  #这里true和false只是为了开始和结束
    while clusterChanged:
        clusterChanged=False  
        for i in range(m):
            minDist=np.if  #无穷
            minIndex=-1  #因为是0,1,2才给-1
            for j in range(k):
                #k就是那三个中心点
                distJI=distMeas((centroids[j,:],dataSet[i,:])) #这里是 中心点与各个点之间的坐标
                if distJI<minDist:
                    minDist=distJI
                    minIndex=j #下一个循环迭戈中心点的dist
                #再循环 就是到第二个中心点的dist
#这里是他俩相等了,变成false,不再循环  注意这个表示的是取得这个纵横坐标的值
            if clusterAssment[i,0]!=minIndex:
#这个表示类别变了,不看后面的在这纠结了好久
               clusterChanged=True  #如果相等不再变了,就是false,结束循环
            clusterAssment[i,:]=minIndex,minDist
#将当前中心点和最小距离赋给clusterAssement的一行
#这个时候80个点到三个随机中心点的距离做完了
    for cent in range(k):
        ptsInClust=dataSet[np.nonzero(clusterAssment[:,0].A==cent)[0]]
        centroids[cent,:]=np.mean(ptsInCluster,axis=0)#跨行
    return centroids,clusterAssement
#返回当前三个中心点的坐标,每个点的类别号,和到当前中心点的最小距离

if __name__ == '__main__':
    dataMat=np.mat(loadDataSet('./testSet.txt'))
    k=3
    centroids,clusterAssment=KMeans(dataMat,k,distMeas=distEclud,creatCent=randCent)
    print centroids
    print clusterAssment

#前面框架完整之后直接带入,写进main函数就好了
#流程就是 数据导入和存储, 欧式距离  ,找中心点 ,合并
    
                
            
        
    
                
    
        
发布了39 篇原创文章 · 获赞 1 · 访问量 484

猜你喜欢

转载自blog.csdn.net/qq_40647378/article/details/103377775